Merge "[Ravenwood] Support java_defaults for ravenwood properties" into main
diff --git a/Android.bp b/Android.bp
index d0f97db..cbe1c7b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -164,6 +164,7 @@
     name: "product_config",
     visibility: [
         "//build/make/target/product/generic",
+        "//build/soong/fsgen",
     ],
 }
 
diff --git a/android/Android.bp b/android/Android.bp
index 87ac657..1ed2dba 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -9,6 +9,7 @@
         "blueprint",
         "blueprint-bootstrap",
         "blueprint-depset",
+        "blueprint-gobtools",
         "blueprint-metrics",
         "sbox_proto",
         "soong",
diff --git a/android/build_prop.go b/android/build_prop.go
index ede93ed..7c3c506 100644
--- a/android/build_prop.go
+++ b/android/build_prop.go
@@ -20,7 +20,7 @@
 
 func init() {
 	ctx := InitRegistrationContext
-	ctx.RegisterModuleType("build_prop", buildPropFactory)
+	ctx.RegisterModuleType("build_prop", BuildPropFactory)
 }
 
 type buildPropProperties struct {
@@ -65,6 +65,9 @@
 		return ctx.Config().ProductPropFiles(ctx)
 	} else if partition == "odm" {
 		return ctx.Config().OdmPropFiles(ctx)
+	} else if partition == "vendor" {
+		// TODO (b/375500423): Add android-info.txt to prop files
+		return ctx.Config().VendorPropFiles(ctx)
 	}
 	return nil
 }
@@ -104,6 +107,7 @@
 	"system_ext",
 	"product",
 	"odm",
+	"vendor",
 }
 
 func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
@@ -187,7 +191,7 @@
 // build_prop module generates {partition}/build.prop file. At first common build properties are
 // printed based on Soong config variables. And then prop_files are printed as-is. Finally,
 // post_process_props tool is run to check if the result build.prop is valid or not.
-func buildPropFactory() Module {
+func BuildPropFactory() Module {
 	module := &buildPropModule{}
 	module.AddProperties(&module.properties)
 	InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
diff --git a/android/compliance_metadata.go b/android/compliance_metadata.go
index d28831e..0b876c3 100644
--- a/android/compliance_metadata.go
+++ b/android/compliance_metadata.go
@@ -23,6 +23,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/gobtools"
 )
 
 var (
@@ -146,11 +147,11 @@
 }
 
 func (c *ComplianceMetadataInfo) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[complianceMetadataInfoGob](c)
+	return gobtools.CustomGobEncode[complianceMetadataInfoGob](c)
 }
 
 func (c *ComplianceMetadataInfo) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[complianceMetadataInfoGob](data, c)
+	return gobtools.CustomGobDecode[complianceMetadataInfoGob](data, c)
 }
 
 func (c *ComplianceMetadataInfo) SetStringValue(propertyName string, value string) {
diff --git a/android/config.go b/android/config.go
index 1e51840..feed22f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -2195,6 +2195,10 @@
 	return PathsForSource(ctx, c.productVariables.OdmPropFiles)
 }
 
+func (c *config) VendorPropFiles(ctx PathContext) Paths {
+	return PathsForSource(ctx, c.productVariables.VendorPropFiles)
+}
+
 func (c *config) ExtraAllowedDepsTxt() string {
 	return String(c.productVariables.ExtraAllowedDepsTxt)
 }
diff --git a/android/early_module_context.go b/android/early_module_context.go
index 9b1a9ea..5e971ef 100644
--- a/android/early_module_context.go
+++ b/android/early_module_context.go
@@ -21,9 +21,20 @@
 	"github.com/google/blueprint"
 )
 
+// ModuleErrorContext provides only methods to report errors about the current module.
+type ModuleErrorContext interface {
+	// ModuleErrorf reports an error at the line number of the module type in the module definition.
+	ModuleErrorf(fmt string, args ...interface{})
+
+	// PropertyErrorf reports an error at the line number of a property in the module definition.
+	PropertyErrorf(property, fmt string, args ...interface{})
+}
+
 // EarlyModuleContext provides methods that can be called early, as soon as the properties have
 // been parsed into the module and before any mutators have run.
 type EarlyModuleContext interface {
+	ModuleErrorContext
+
 	// Module returns the current module as a Module.  It should rarely be necessary, as the module already has a
 	// reference to itself.
 	Module() Module
@@ -49,12 +60,6 @@
 	// Errorf reports an error at the specified position of the module definition file.
 	Errorf(pos scanner.Position, fmt string, args ...interface{})
 
-	// ModuleErrorf reports an error at the line number of the module type in the module definition.
-	ModuleErrorf(fmt string, args ...interface{})
-
-	// PropertyErrorf reports an error at the line number of a property in the module definition.
-	PropertyErrorf(property, fmt string, args ...interface{})
-
 	// OtherModulePropertyErrorf reports an error at the line number of a property in the given module definition.
 	OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{})
 
diff --git a/android/image.go b/android/image.go
index 012267a..e8b6352 100644
--- a/android/image.go
+++ b/android/image.go
@@ -98,16 +98,47 @@
 	DebugRamdiskVariation string = "debug_ramdisk"
 )
 
+type imageInterfaceContextAdapter struct {
+	IncomingTransitionContext
+	kind moduleKind
+}
+
+var _ ImageInterfaceContext = (*imageInterfaceContextAdapter)(nil)
+
+func (e *imageInterfaceContextAdapter) Platform() bool {
+	return e.kind == platformModule
+}
+
+func (e *imageInterfaceContextAdapter) DeviceSpecific() bool {
+	return e.kind == deviceSpecificModule
+}
+
+func (e *imageInterfaceContextAdapter) SocSpecific() bool {
+	return e.kind == socSpecificModule
+}
+
+func (e *imageInterfaceContextAdapter) ProductSpecific() bool {
+	return e.kind == productSpecificModule
+}
+
+func (e *imageInterfaceContextAdapter) SystemExtSpecific() bool {
+	return e.kind == systemExtSpecificModule
+}
+
+func imageMutatorBeginMutator(ctx BottomUpMutatorContext) {
+	if m, ok := ctx.Module().(ImageInterface); ok && ctx.Os() == Android {
+		m.ImageMutatorBegin(ctx)
+	}
+}
+
 // imageTransitionMutator creates variants for modules that implement the ImageInterface that
 // allow them to build differently for each partition (recovery, core, vendor, etc.).
 type imageTransitionMutator struct{}
 
-func (imageTransitionMutator) Split(ctx BaseModuleContext) []string {
+func getImageVariations(ctx ImageInterfaceContext) []string {
 	var variations []string
 
 	if m, ok := ctx.Module().(ImageInterface); ctx.Os() == Android && ok {
-		m.ImageMutatorBegin(ctx)
-
 		if m.CoreVariantNeeded(ctx) {
 			variations = append(variations, CoreVariation)
 		}
@@ -141,6 +172,10 @@
 	return variations
 }
 
+func (imageTransitionMutator) Split(ctx BaseModuleContext) []string {
+	return getImageVariations(ctx)
+}
+
 func (imageTransitionMutator) OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string {
 	return sourceVariation
 }
@@ -149,6 +184,16 @@
 	if _, ok := ctx.Module().(ImageInterface); ctx.Os() != Android || !ok {
 		return CoreVariation
 	}
+	variations := getImageVariations(&imageInterfaceContextAdapter{
+		IncomingTransitionContext: ctx,
+		kind:                      determineModuleKind(ctx.Module().base(), ctx),
+	})
+	// If there's only 1 possible variation, use that. This is a holdover from when blueprint,
+	// when adding dependencies, would use the only variant of a module regardless of its variations
+	// if only 1 variant existed.
+	if len(variations) == 1 {
+		return variations[0]
+	}
 	return incomingVariation
 }
 
diff --git a/android/licenses.go b/android/licenses.go
index 949d678..53d0555 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -15,7 +15,10 @@
 package android
 
 import (
+	"fmt"
+	"path/filepath"
 	"reflect"
+	"strings"
 	"sync"
 
 	"github.com/google/blueprint"
@@ -155,7 +158,25 @@
 	}
 
 	licenses := getLicenses(ctx, m)
-	ctx.AddVariationDependencies(nil, licensesTag, licenses...)
+
+	var fullyQualifiedLicenseNames []string
+	for _, license := range licenses {
+		fullyQualifiedLicenseName := license
+		if !strings.HasPrefix(license, "//") {
+			licenseModuleDir := ctx.OtherModuleDir(m)
+			for licenseModuleDir != "." && !ctx.OtherModuleExists(fmt.Sprintf("//%s:%s", licenseModuleDir, license)) {
+				licenseModuleDir = filepath.Dir(licenseModuleDir)
+			}
+			if licenseModuleDir == "." {
+				fullyQualifiedLicenseName = license
+			} else {
+				fullyQualifiedLicenseName = fmt.Sprintf("//%s:%s", licenseModuleDir, license)
+			}
+		}
+		fullyQualifiedLicenseNames = append(fullyQualifiedLicenseNames, fullyQualifiedLicenseName)
+	}
+
+	ctx.AddVariationDependencies(nil, licensesTag, fullyQualifiedLicenseNames...)
 }
 
 // Verifies the license and license_kind dependencies are each the correct kind of module.
diff --git a/android/module.go b/android/module.go
index ec0f446..6ef5c6a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -16,7 +16,6 @@
 
 import (
 	"fmt"
-	"github.com/google/blueprint/depset"
 	"net/url"
 	"path/filepath"
 	"reflect"
@@ -25,6 +24,8 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/depset"
+	"github.com/google/blueprint/gobtools"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -118,6 +119,10 @@
 	// The usage of this method is experimental and should not be used outside of fsgen package.
 	// This will be removed once product packaging migration to Soong is complete.
 	DecodeMultilib(ctx ConfigContext) (string, string)
+
+	// WARNING: This should not be used outside build/soong/fsgen
+	// Overrides returns the list of modules which should not be installed if this module is installed.
+	Overrides() []string
 }
 
 // Qualified id for a module
@@ -1662,7 +1667,7 @@
 	}
 }
 
-func determineModuleKind(m *ModuleBase, ctx blueprint.EarlyModuleContext) moduleKind {
+func determineModuleKind(m *ModuleBase, ctx ModuleErrorContext) moduleKind {
 	var socSpecific = Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Proprietary) || Bool(m.commonProperties.Soc_specific)
 	var deviceSpecific = Bool(m.commonProperties.Device_specific)
 	var productSpecific = Bool(m.commonProperties.Product_specific)
@@ -2201,11 +2206,11 @@
 }
 
 func (k *katiInstall) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[katiInstallGob](k)
+	return gobtools.CustomGobEncode[katiInstallGob](k)
 }
 
 func (k *katiInstall) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[katiInstallGob](data, k)
+	return gobtools.CustomGobDecode[katiInstallGob](data, k)
 }
 
 type extraFilesZip struct {
@@ -2231,11 +2236,11 @@
 }
 
 func (e *extraFilesZip) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[extraFilesZipGob](e)
+	return gobtools.CustomGobEncode[extraFilesZipGob](e)
 }
 
 func (e *extraFilesZip) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[extraFilesZipGob](data, e)
+	return gobtools.CustomGobDecode[extraFilesZipGob](data, e)
 }
 
 type katiInstalls []katiInstall
@@ -2291,6 +2296,10 @@
 	return decodeMultilib(ctx, m)
 }
 
+func (m *ModuleBase) Overrides() []string {
+	return m.commonProperties.Overrides
+}
+
 type ConfigContext interface {
 	Config() Config
 }
diff --git a/android/module_proxy.go b/android/module_proxy.go
index 0f552dd..2a65072 100644
--- a/android/module_proxy.go
+++ b/android/module_proxy.go
@@ -205,3 +205,7 @@
 func (m ModuleProxy) DecodeMultilib(ctx ConfigContext) (string, string) {
 	panic("method is not implemented on ModuleProxy")
 }
+
+func (m ModuleProxy) Overrides() []string {
+	panic("method is not implemented on ModuleProxy")
+}
diff --git a/android/mutator.go b/android/mutator.go
index f2b94ac..4ddc606 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -151,6 +151,7 @@
 
 func registerArchMutator(ctx RegisterMutatorsContext) {
 	ctx.Transition("os", &osTransitionMutator{})
+	ctx.BottomUp("image_begin", imageMutatorBeginMutator)
 	ctx.Transition("image", &imageTransitionMutator{})
 	ctx.Transition("arch", &archTransitionMutator{})
 }
@@ -339,6 +340,7 @@
 type IncomingTransitionContext interface {
 	ArchModuleContext
 	ModuleProviderContext
+	ModuleErrorContext
 
 	// Module returns the target of the dependency edge for which the transition
 	// is being computed
@@ -539,6 +541,14 @@
 	return c.bp.Provider(provider)
 }
 
+func (c *incomingTransitionContextImpl) ModuleErrorf(fmt string, args ...interface{}) {
+	c.bp.ModuleErrorf(fmt, args)
+}
+
+func (c *incomingTransitionContextImpl) PropertyErrorf(property, fmt string, args ...interface{}) {
+	c.bp.PropertyErrorf(property, fmt, args)
+}
+
 func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string {
 	if m, ok := bpctx.Module().(Module); ok {
 		ctx := incomingTransitionContextPool.Get().(*incomingTransitionContextImpl)
diff --git a/android/neverallow.go b/android/neverallow.go
index 57373d5..44ac2cd 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -289,8 +289,10 @@
 			Without("visibility", "//trusty/vendor/google/aosp/scripts").Because(reason),
 		NeverAllow().
 			ModuleType("genrule").
-			Without("name", "lk.elf.arm64").
-			Without("name", "lk.elf.x86_64").
+			Without("name", "trusty-arm64.lk.elf.gen").
+			Without("name", "trusty-arm64-test.lk.elf.gen").
+			Without("name", "trusty-x86_64.lk.elf.gen").
+			Without("name", "trusty-x86_64-test.lk.elf.gen").
 			WithMatcher("dir_srcs", isSetMatcherInstance).Because(reason),
 	}
 }
diff --git a/android/packaging.go b/android/packaging.go
index fe76bfc..acafcd4 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -21,6 +21,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/gobtools"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -109,11 +110,11 @@
 }
 
 func (p *PackagingSpec) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[packagingSpecGob](p)
+	return gobtools.CustomGobEncode[packagingSpecGob](p)
 }
 
 func (p *PackagingSpec) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[packagingSpecGob](data, p)
+	return gobtools.CustomGobDecode[packagingSpecGob](data, p)
 }
 
 func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
diff --git a/android/path_properties.go b/android/path_properties.go
index a79b5a2..f3c62ea 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -92,13 +92,18 @@
 	// properties tagged path_device_first_prefer32 get the first 32 bit target if one is available,
 	// otherwise they use the first 64 bit target
 	if len(pathDeviceFirstPrefer32Properties) > 0 {
-		firstPrefer32Target := FirstTarget(ctx.Config().Targets[Android], "lib32", "lib64")
-		if len(firstPrefer32Target) == 0 {
+		var targets []Target
+		if ctx.Config().IgnorePrefer32OnDevice() {
+			targets, _ = decodeMultilibTargets("first", ctx.Config().Targets[Android], false)
+		} else {
+			targets, _ = decodeMultilibTargets("first_prefer32", ctx.Config().Targets[Android], false)
+		}
+		if len(targets) == 0 {
 			ctx.ModuleErrorf("Could not find a first_prefer32 target")
 		} else {
 			for _, s := range pathDeviceFirstPrefer32Properties {
 				if m, t := SrcIsModuleWithTag(s); m != "" {
-					ctx.AddVariationDependencies(firstPrefer32Target[0].Variations(), sourceOrOutputDepTag(m, t), m)
+					ctx.AddVariationDependencies(targets[0].Variations(), sourceOrOutputDepTag(m, t), m)
 				}
 			}
 		}
diff --git a/android/paths.go b/android/paths.go
index 371aed8..bf2c3a0 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -24,6 +24,7 @@
 	"strings"
 
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/gobtools"
 	"github.com/google/blueprint/pathtools"
 )
 
@@ -368,11 +369,11 @@
 }
 
 func (p OptionalPath) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[optionalPathGob](&p)
+	return gobtools.CustomGobEncode[optionalPathGob](&p)
 }
 
 func (p *OptionalPath) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[optionalPathGob](data, p)
+	return gobtools.CustomGobDecode[optionalPathGob](data, p)
 }
 
 // Valid returns whether there is a valid path
@@ -1157,11 +1158,11 @@
 }
 
 func (p basePath) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[basePathGob](&p)
+	return gobtools.CustomGobEncode[basePathGob](&p)
 }
 
 func (p *basePath) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[basePathGob](data, p)
+	return gobtools.CustomGobDecode[basePathGob](data, p)
 }
 
 func (p basePath) Ext() string {
@@ -1435,11 +1436,11 @@
 }
 
 func (p OutputPath) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[outputPathGob](&p)
+	return gobtools.CustomGobEncode[outputPathGob](&p)
 }
 
 func (p *OutputPath) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[outputPathGob](data, p)
+	return gobtools.CustomGobDecode[outputPathGob](data, p)
 }
 
 func (p OutputPath) withRel(rel string) OutputPath {
@@ -1869,11 +1870,11 @@
 }
 
 func (p InstallPath) GobEncode() ([]byte, error) {
-	return blueprint.CustomGobEncode[installPathGob](&p)
+	return gobtools.CustomGobEncode[installPathGob](&p)
 }
 
 func (p *InstallPath) GobDecode(data []byte) error {
-	return blueprint.CustomGobDecode[installPathGob](data, p)
+	return gobtools.CustomGobDecode[installPathGob](data, p)
 }
 
 // Will panic if called from outside a test environment.
diff --git a/android/variable.go b/android/variable.go
index c352942..6693d91 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -521,6 +521,7 @@
 	SystemExtPropFiles []string `json:",omitempty"`
 	ProductPropFiles   []string `json:",omitempty"`
 	OdmPropFiles       []string `json:",omitempty"`
+	VendorPropFiles    []string `json:",omitempty"`
 
 	EnableUffdGc *string `json:",omitempty"`
 
diff --git a/apex/aconfig_test.go b/apex/aconfig_test.go
index bb811f5..2ab61b3 100644
--- a/apex/aconfig_test.go
+++ b/apex/aconfig_test.go
@@ -33,6 +33,7 @@
 })
 
 func TestValidationAcrossContainersExportedPass(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name string
 		bp   string
@@ -294,6 +295,7 @@
 	}
 	for _, test := range testCases {
 		t.Run(test.name, func(t *testing.T) {
+			t.Parallel()
 			android.GroupFixturePreparers(
 				java.PrepareForTestWithJavaDefaultModules,
 				cc.PrepareForTestWithCcBuildComponents,
@@ -309,6 +311,7 @@
 }
 
 func TestValidationAcrossContainersNotExportedFail(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name          string
 		expectedError string
@@ -709,6 +712,7 @@
 	}
 	for _, test := range testCases {
 		t.Run(test.name, func(t *testing.T) {
+			t.Parallel()
 			errorHandler := android.FixtureExpectsNoErrors
 			if test.expectedError != "" {
 				errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
@@ -730,6 +734,7 @@
 }
 
 func TestValidationNotPropagateAcrossShared(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name string
 		bp   string
@@ -786,6 +791,7 @@
 	}
 	for _, test := range testCases {
 		t.Run(test.name, func(t *testing.T) {
+			t.Parallel()
 			android.GroupFixturePreparers(
 				java.PrepareForTestWithJavaDefaultModules,
 				cc.PrepareForTestWithCcBuildComponents,
diff --git a/apex/apex.go b/apex/apex.go
index 30b16ee..0c56c30 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -833,6 +833,7 @@
 		deps.Merge(ctx, a.properties.Multilib.Both)
 		deps.Merge(ctx, ApexNativeDependencies{
 			Native_shared_libs: a.properties.Native_shared_libs,
+			Rust_dyn_libs:      a.properties.Rust_dyn_libs,
 			Tests:              a.properties.Tests,
 			Jni_libs:           a.properties.Jni_libs,
 		})
diff --git a/apex/apex_test.go b/apex/apex_test.go
index bf4158c..b50ffe6 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -308,6 +308,7 @@
 
 // Minimal test
 func TestBasicApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_defaults {
 			name: "myapex-defaults",
@@ -392,7 +393,7 @@
 			name: "foo.rust",
 			srcs: ["foo.rs"],
 			rlibs: ["libfoo.rlib.rust"],
-			rustlibs: ["libfoo.dylib.rust"],
+			rustlibs: ["libfoo.transitive.dylib.rust"],
 			apex_available: ["myapex"],
 		}
 
@@ -419,6 +420,13 @@
 			apex_available: ["myapex"],
 		}
 
+		rust_library_dylib {
+			name: "libfoo.transitive.dylib.rust",
+			srcs: ["foo.rs"],
+			crate_name: "foo",
+			apex_available: ["myapex"],
+		}
+
 		rust_ffi_shared {
 			name: "libfoo.ffi",
 			srcs: ["foo.rs"],
@@ -454,7 +462,7 @@
 				"//apex_available:platform",
 				"myapex",
 			],
-    }
+		}
 
 		cc_library_static {
 			name: "libstatic",
@@ -546,6 +554,7 @@
 	ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000")
 	ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.rlib.rust"), "android_arm64_armv8-a_rlib_dylib-std_apex10000")
 	ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000")
+	ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.transitive.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000")
 	ensureListContains(t, ctx.ModuleVariantsForTests("libbar.ffi"), "android_arm64_armv8-a_shared_apex10000")
 	ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.shared_from_rust"), "android_arm64_armv8-a_shared_apex10000")
 
@@ -555,6 +564,7 @@
 	ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
 	ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar")
 	ensureContains(t, copyCmds, "image.apex/lib64/libfoo.dylib.rust.dylib.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libfoo.transitive.dylib.rust.dylib.so")
 	ensureContains(t, copyCmds, "image.apex/lib64/libfoo.ffi.so")
 	ensureContains(t, copyCmds, "image.apex/lib64/libbar.ffi.so")
 	ensureContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
@@ -605,6 +615,7 @@
 }
 
 func TestDefaults(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_defaults {
 			name: "myapex-defaults",
@@ -687,6 +698,7 @@
 }
 
 func TestApexManifest(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -709,6 +721,7 @@
 }
 
 func TestApexManifestMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_defaults {
 			name: "my_defaults",
@@ -782,6 +795,7 @@
 }
 
 func TestApexWithDessertSha(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_defaults {
 			name: "my_defaults",
@@ -855,6 +869,7 @@
 }
 
 func TestFileContexts(t *testing.T) {
+	t.Parallel()
 	for _, vendor := range []bool{true, false} {
 		prop := ""
 		if vendor {
@@ -889,6 +904,7 @@
 }
 
 func TestApexWithStubs(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1060,6 +1076,7 @@
 }
 
 func TestApexShouldNotEmbedStubVariant(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "myapex" .*: native_shared_libs: "libbar" is a stub`, `
 		apex {
 			name: "myapex",
@@ -1086,6 +1103,7 @@
 }
 
 func TestApexCanUsePrivateApis(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1336,6 +1354,7 @@
 }
 
 func TestApexWithExplicitStubsDependency(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex2",
@@ -1422,6 +1441,7 @@
 }
 
 func TestApexWithRuntimeLibsDependency(t *testing.T) {
+	t.Parallel()
 	/*
 		myapex
 		  |
@@ -1550,6 +1570,7 @@
 )
 
 func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(prepareForTestOfRuntimeApexWithHwasan).RunTestWithBp(t, `
 		cc_library {
 			name: "libc",
@@ -1603,6 +1624,7 @@
 }
 
 func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestOfRuntimeApexWithHwasan,
 		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -1658,6 +1680,7 @@
 }
 
 func TestApexDependsOnLLNDKTransitively(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name          string
 		minSdkVersion string
@@ -1682,6 +1705,7 @@
 	}
 	for _, tc := range testcases {
 		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
 			ctx := testApex(t, `
 			apex {
 				name: "myapex",
@@ -1749,6 +1773,7 @@
 }
 
 func TestApexWithSystemLibsStubs(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1841,6 +1866,7 @@
 }
 
 func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) {
+	t.Parallel()
 	// there are three links between liba --> libz.
 	// 1) myapex -> libx -> liba -> libz    : this should be #30 link
 	// 2) otherapex -> liby -> liba -> libz : this should be #30 link
@@ -1929,6 +1955,7 @@
 }
 
 func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -1981,6 +2008,7 @@
 }
 
 func TestApexMinSdkVersion_SupportsCodeNames_JavaLibs(t *testing.T) {
+	t.Parallel()
 	testApex(t, `
 		apex {
 			name: "myapex",
@@ -2011,6 +2039,7 @@
 }
 
 func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2058,6 +2087,7 @@
 }
 
 func TestApexMinSdkVersion_InVendorApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2111,6 +2141,7 @@
 }
 
 func TestTrackAllowedDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2178,6 +2209,7 @@
 }
 
 func TestTrackCustomAllowedDepsInvalidDefaultTxt(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2250,6 +2282,7 @@
 }
 
 func TestTrackCustomAllowedDepsWithDefaultTxt(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2323,6 +2356,7 @@
 }
 
 func TestTrackAllowedDeps_SkipWithoutAllowedDepsTxt(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2344,6 +2378,7 @@
 }
 
 func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2399,6 +2434,7 @@
 )
 
 func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2438,6 +2474,7 @@
 }
 
 func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2468,6 +2505,7 @@
 }
 
 func TestApexMinSdkVersion_ErrorIfIncompatibleVersion(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "mylib".*: should support min_sdk_version\(29\)`, `
 		apex {
 			name: "myapex",
@@ -2573,6 +2611,7 @@
 }
 
 func TestApexMinSdkVersion_Okay(t *testing.T) {
+	t.Parallel()
 	testApex(t, `
 		apex {
 			name: "myapex",
@@ -2633,6 +2672,7 @@
 }
 
 func TestApexMinSdkVersion_MinApiForArch(t *testing.T) {
+	t.Parallel()
 	// Tests that an apex dependency with min_sdk_version higher than the
 	// min_sdk_version of the apex is allowed as long as the dependency's
 	// min_sdk_version is less than or equal to the api level that the
@@ -2665,6 +2705,7 @@
 }
 
 func TestJavaStableSdkVersion(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name          string
 		expectedError string
@@ -2804,6 +2845,7 @@
 			continue
 		}
 		t.Run(test.name, func(t *testing.T) {
+			t.Parallel()
 			errorHandler := android.FixtureExpectsNoErrors
 			if test.expectedError != "" {
 				errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
@@ -2862,6 +2904,7 @@
 }
 
 func TestApexMinSdkVersion_ErrorIfDepIsNewer_Java(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "bar".*: should support min_sdk_version\(29\) for "myapex"`, `
 		apex {
 			name: "myapex",
@@ -2898,6 +2941,7 @@
 }
 
 func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2951,6 +2995,7 @@
 }
 
 func TestApexMinSdkVersion_WorksWithSdkCodename(t *testing.T) {
+	t.Parallel()
 	withSAsActiveCodeNames := android.FixtureModifyProductVariables(
 		func(variables android.FixtureProductVariables) {
 			variables.Platform_sdk_codename = proptools.StringPtr("S")
@@ -2983,6 +3028,7 @@
 }
 
 func TestApexMinSdkVersion_WorksWithActiveCodenames(t *testing.T) {
+	t.Parallel()
 	withSAsActiveCodeNames := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
 		variables.Platform_sdk_codename = proptools.StringPtr("S")
 		variables.Platform_version_active_codenames = []string{"S", "T"}
@@ -3021,6 +3067,7 @@
 }
 
 func TestFilesInSubDir(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3090,6 +3137,7 @@
 }
 
 func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3148,6 +3196,7 @@
 }
 
 func TestVendorApex(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForApexTest,
 		android.FixtureModifyConfig(android.SetKatiEnabledForTests),
@@ -3198,6 +3247,7 @@
 }
 
 func TestProductVariant(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3230,6 +3280,7 @@
 }
 
 func TestApex_withPrebuiltFirmware(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		name           string
 		additionalProp string
@@ -3239,6 +3290,7 @@
 	}
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
 			ctx := testApex(t, `
 				apex {
 					name: "myapex",
@@ -3267,6 +3319,7 @@
 }
 
 func TestAndroidMk_VendorApexRequired(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3329,6 +3382,7 @@
 }
 
 func TestStaticLinking(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3371,6 +3425,7 @@
 }
 
 func TestKeys(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex_keytest",
@@ -3428,7 +3483,9 @@
 }
 
 func TestCertificate(t *testing.T) {
+	t.Parallel()
 	t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) {
+		t.Parallel()
 		ctx := testApex(t, `
 			apex {
 				name: "myapex",
@@ -3447,6 +3504,7 @@
 		}
 	})
 	t.Run("override when unspecified", func(t *testing.T) {
+		t.Parallel()
 		ctx := testApex(t, `
 			apex {
 				name: "myapex_keytest",
@@ -3470,6 +3528,7 @@
 		}
 	})
 	t.Run("if specified as :module, it respects the prop", func(t *testing.T) {
+		t.Parallel()
 		ctx := testApex(t, `
 			apex {
 				name: "myapex",
@@ -3493,6 +3552,7 @@
 		}
 	})
 	t.Run("override when specifiec as <:module>", func(t *testing.T) {
+		t.Parallel()
 		ctx := testApex(t, `
 			apex {
 				name: "myapex_keytest",
@@ -3517,6 +3577,7 @@
 		}
 	})
 	t.Run("if specified as name, finds it from DefaultDevKeyDir", func(t *testing.T) {
+		t.Parallel()
 		ctx := testApex(t, `
 			apex {
 				name: "myapex",
@@ -3536,6 +3597,7 @@
 		}
 	})
 	t.Run("override when specified as <name>", func(t *testing.T) {
+		t.Parallel()
 		ctx := testApex(t, `
 			apex {
 				name: "myapex_keytest",
@@ -3562,6 +3624,7 @@
 }
 
 func TestMacro(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3655,6 +3718,7 @@
 }
 
 func TestHeaderLibsDependency(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -3858,6 +3922,7 @@
 }
 
 func TestVndkApexVersion(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.v27",
@@ -3927,6 +3992,7 @@
 }
 
 func TestVndkApexNameRule(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.v29",
@@ -3959,6 +4025,7 @@
 }
 
 func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "com.android.vndk.v30" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
 		apex_vndk {
 			name: "com.android.vndk.v30",
@@ -3989,6 +4056,7 @@
 }
 
 func TestVndkApexWithBinder32(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_vndk {
 			name: "com.android.vndk.v27",
@@ -4067,6 +4135,7 @@
 }
 
 func TestDependenciesInApexManifest(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex_nodep",
@@ -4200,6 +4269,7 @@
 }
 
 func TestOverrideApexManifestDefaultVersion(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4234,6 +4304,7 @@
 }
 
 func TestCompileMultilibProp(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		compileMultiLibProp string
 		containedLibs       []string
@@ -4304,6 +4375,7 @@
 }
 
 func TestNonTestApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4357,6 +4429,7 @@
 }
 
 func TestTestApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_test {
 			name: "myapex",
@@ -4406,6 +4479,7 @@
 }
 
 func TestLibzVendorIsntStable(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 	apex {
 		name: "myapex",
@@ -4472,6 +4546,7 @@
 }
 
 func TestApexWithTarget(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4563,6 +4638,7 @@
 }
 
 func TestApexWithArch(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4638,6 +4714,7 @@
 }
 
 func TestApexWithShBinary(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4668,6 +4745,7 @@
 }
 
 func TestApexInVariousPartition(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		propName, partition string
 	}{
@@ -4680,6 +4758,7 @@
 	}
 	for _, tc := range testcases {
 		t.Run(tc.propName+":"+tc.partition, func(t *testing.T) {
+			t.Parallel()
 			ctx := testApex(t, `
 				apex {
 					name: "myapex",
@@ -4706,6 +4785,7 @@
 }
 
 func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4725,6 +4805,7 @@
 }
 
 func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, `
 		apex {
 			name: "myapex",
@@ -4744,6 +4825,7 @@
 }
 
 func TestFileContexts_ProductSpecificApexes(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: file_contexts: cannot find`, `
 		apex {
 			name: "myapex",
@@ -4783,6 +4865,7 @@
 }
 
 func TestFileContexts_SetViaFileGroup(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -4811,6 +4894,7 @@
 }
 
 func TestApexKeyFromOtherModule(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_key {
 			name: "myapex.key",
@@ -4844,6 +4928,7 @@
 }
 
 func TestPrebuilt(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		prebuilt_apex {
 			name: "myapex",
@@ -4878,6 +4963,7 @@
 }
 
 func TestPrebuiltMissingSrc(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "myapex" variant "android_common_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, `
 		prebuilt_apex {
 			name: "myapex",
@@ -4886,6 +4972,7 @@
 }
 
 func TestPrebuiltFilenameOverride(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		prebuilt_apex {
 			name: "myapex",
@@ -4909,6 +4996,7 @@
 }
 
 func TestApexSetFilenameOverride(t *testing.T) {
+	t.Parallel()
 	testApex(t, `
 		apex_set {
  			name: "com.company.android.myapex",
@@ -4938,6 +5026,7 @@
 }
 
 func TestPrebuiltOverrides(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		prebuilt_apex {
 			name: "myapex.prebuilt",
@@ -4964,6 +5053,7 @@
 }
 
 func TestPrebuiltApexName(t *testing.T) {
+	t.Parallel()
 	testApex(t, `
 		prebuilt_apex {
 			name: "com.company.android.myapex",
@@ -4982,6 +5072,7 @@
 }
 
 func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) {
+	t.Parallel()
 	_ = android.GroupFixturePreparers(
 		java.PrepareForTestWithJavaDefaultModules,
 		PrepareForTestWithApexBuildComponents,
@@ -5032,6 +5123,7 @@
 }
 
 func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
+	t.Parallel()
 	preparer := android.GroupFixturePreparers(
 		java.FixtureConfigureApexBootJars("myapex:libfoo", "myapex:libbar"),
 		// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
@@ -5077,6 +5169,7 @@
 	}
 
 	t.Run("prebuilt only", func(t *testing.T) {
+		t.Parallel()
 		bp := `
 		prebuilt_apex {
 			name: "myapex",
@@ -5138,6 +5231,7 @@
 	})
 
 	t.Run("apex_set only", func(t *testing.T) {
+		t.Parallel()
 		bp := `
 		apex_set {
 			name: "myapex",
@@ -5228,6 +5322,7 @@
 	})
 
 	t.Run("prebuilt with source library preferred", func(t *testing.T) {
+		t.Parallel()
 		bp := `
 		prebuilt_apex {
 			name: "myapex",
@@ -5301,6 +5396,7 @@
 	})
 
 	t.Run("prebuilt library preferred with source", func(t *testing.T) {
+		t.Parallel()
 		bp := `
 		apex {
 			name: "myapex",
@@ -5403,6 +5499,7 @@
 	})
 
 	t.Run("prebuilt with source apex preferred", func(t *testing.T) {
+		t.Parallel()
 		bp := `
 		apex {
 			name: "myapex",
@@ -5501,6 +5598,7 @@
 	})
 
 	t.Run("prebuilt preferred with source apex disabled", func(t *testing.T) {
+		t.Parallel()
 		bp := `
 		apex {
 			name: "myapex",
@@ -5612,6 +5710,7 @@
 	})
 
 	t.Run("Co-existing unflagged apexes should create a duplicate module error", func(t *testing.T) {
+		t.Parallel()
 		bp := `
 		// Source
 		apex {
@@ -5691,6 +5790,7 @@
 }
 
 func TestApexWithTests(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_test {
 			name: "myapex",
@@ -5766,6 +5866,7 @@
 }
 
 func TestErrorsIfDepsAreNotEnabled(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `module "myapex" .* depends on disabled module "libfoo"`, `
 		apex {
 			name: "myapex",
@@ -5841,6 +5942,7 @@
 }
 
 func TestApexWithApps(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -5935,6 +6037,7 @@
 }
 
 func TestApexWithAppImportBuildId(t *testing.T) {
+	t.Parallel()
 	invalidBuildIds := []string{"../", "a b", "a/b", "a/b/../c", "/a"}
 	for _, id := range invalidBuildIds {
 		message := fmt.Sprintf("Unable to use build id %s as filename suffix", id)
@@ -5965,6 +6068,7 @@
 }
 
 func TestApexWithAppImports(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -6014,6 +6118,7 @@
 }
 
 func TestApexWithAppImportsPrefer(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -6056,6 +6161,7 @@
 }
 
 func TestApexWithTestHelperApp(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -6089,6 +6195,7 @@
 }
 
 func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
+	t.Parallel()
 	// libfoo's apex_available comes from cc_defaults
 	testApexError(t, `requires "libfoo" that doesn't list the APEX under 'apex_available'.`, `
 	apex {
@@ -6125,6 +6232,7 @@
 }
 
 func TestApexAvailable_DirectDep(t *testing.T) {
+	t.Parallel()
 	// libfoo is not available to myapex, but only to otherapex
 	testApexError(t, "requires \"libfoo\" that doesn't list the APEX under 'apex_available'.", `
 	apex {
@@ -6243,6 +6351,7 @@
 }
 
 func TestApexAvailable_IndirectDep(t *testing.T) {
+	t.Parallel()
 	// libbbaz is an indirect dep
 	testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.\n\nDependency path:
 .*via tag apex\.dependencyTag\{"sharedLib"\}
@@ -6373,6 +6482,7 @@
 }
 
 func TestApexAvailable_IndirectStaticDep(t *testing.T) {
+	t.Parallel()
 	testApex(t, `
 	apex {
 		name: "myapex",
@@ -6439,6 +6549,7 @@
 }
 
 func TestApexAvailable_InvalidApexName(t *testing.T) {
+	t.Parallel()
 	testApexError(t, "\"otherapex\" is not a valid module name", `
 	apex {
 		name: "myapex",
@@ -6500,7 +6611,9 @@
 }
 
 func TestApexAvailable_ApexAvailableNameWithVersionCodeError(t *testing.T) {
+	t.Parallel()
 	t.Run("negative variant_version produces error", func(t *testing.T) {
+		t.Parallel()
 		testApexError(t, "expected an integer between 0-9; got -1", `
 			apex {
 				name: "myapex",
@@ -6518,6 +6631,7 @@
 	})
 
 	t.Run("variant_version greater than 9 produces error", func(t *testing.T) {
+		t.Parallel()
 		testApexError(t, "expected an integer between 0-9; got 10", `
 			apex {
 				name: "myapex",
@@ -6536,6 +6650,7 @@
 }
 
 func TestApexAvailable_ApexAvailableNameWithVersionCode(t *testing.T) {
+	t.Parallel()
 	context := android.GroupFixturePreparers(
 		android.PrepareForIntegrationTestWithAndroid,
 		PrepareForTestWithApexBuildComponents,
@@ -6593,7 +6708,9 @@
 }
 
 func TestApexAvailable_ApexAvailableName(t *testing.T) {
+	t.Parallel()
 	t.Run("using name of apex that sets apex_available_name is not allowed", func(t *testing.T) {
+		t.Parallel()
 		testApexError(t, "Consider adding \"myapex\" to 'apex_available' property of \"AppFoo\"", `
 			apex {
 				name: "myapex_sminus",
@@ -6627,6 +6744,7 @@
 	})
 
 	t.Run("apex_available_name allows module to be used in two different apexes", func(t *testing.T) {
+		t.Parallel()
 		testApex(t, `
 			apex {
 				name: "myapex_sminus",
@@ -6660,6 +6778,7 @@
 	})
 
 	t.Run("override_apexes work with apex_available_name", func(t *testing.T) {
+		t.Parallel()
 		testApex(t, `
 			override_apex {
 				name: "myoverrideapex_sminus",
@@ -6713,6 +6832,7 @@
 }
 
 func TestApexAvailable_ApexAvailableNameWithOverrides(t *testing.T) {
+	t.Parallel()
 	context := android.GroupFixturePreparers(
 		android.PrepareForIntegrationTestWithAndroid,
 		PrepareForTestWithApexBuildComponents,
@@ -6770,6 +6890,7 @@
 }
 
 func TestApexAvailable_CheckForPlatform(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 	apex {
 		name: "myapex",
@@ -6833,6 +6954,7 @@
 }
 
 func TestApexAvailable_CreatedForApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 	apex {
 		name: "myapex",
@@ -6868,6 +6990,7 @@
 }
 
 func TestApexAvailable_PrefixMatch(t *testing.T) {
+	t.Parallel()
 
 	for _, tc := range []struct {
 		name          string
@@ -6905,6 +7028,7 @@
 		},
 	} {
 		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
 			errorHandler := android.FixtureExpectsNoErrors
 			if tc.expectedError != "" {
 				errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedError)
@@ -6961,6 +7085,7 @@
 }
 
 func TestOverrideApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -7111,6 +7236,7 @@
 }
 
 func TestMinSdkVersionOverride(t *testing.T) {
+	t.Parallel()
 	// Override from 29 to 31
 	minSdkOverride31 := "31"
 	ctx := testApex(t, `
@@ -7170,6 +7296,7 @@
 }
 
 func TestMinSdkVersionOverrideToLowerVersionNoOp(t *testing.T) {
+	t.Parallel()
 	// Attempt to override from 31 to 29, should be a NOOP
 	minSdkOverride29 := "29"
 	ctx := testApex(t, `
@@ -7229,6 +7356,7 @@
 }
 
 func TestLegacyAndroid10Support(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -7289,6 +7417,7 @@
 }
 
 func TestJavaSDKLibrary(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -7328,6 +7457,7 @@
 }
 
 func TestJavaSDKLibraryOverrideApexes(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		override_apex {
 			name: "mycompanyapex",
@@ -7368,6 +7498,7 @@
 }
 
 func TestJavaSDKLibrary_WithinApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -7421,6 +7552,7 @@
 }
 
 func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -7472,6 +7604,7 @@
 }
 
 func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		prebuilt_apis {
 			name: "sdk",
@@ -7562,6 +7695,7 @@
 }
 
 func TestJavaSDKLibrary_ImportOnly(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, `
 		apex {
 			name: "myapex",
@@ -7589,6 +7723,7 @@
 }
 
 func TestCompatConfig(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForApexTest,
 		java.PrepareForTestWithPlatformCompatConfig,
@@ -7635,6 +7770,7 @@
 }
 
 func TestNoDupeApexFiles(t *testing.T) {
+	t.Parallel()
 	android.GroupFixturePreparers(
 		android.PrepareForTestWithAndroidBuildComponents,
 		PrepareForTestWithApexBuildComponents,
@@ -7671,6 +7807,7 @@
 }
 
 func TestApexUnwantedTransitiveDeps(t *testing.T) {
+	t.Parallel()
 	bp := `
 	apex {
 		name: "myapex",
@@ -7707,6 +7844,7 @@
 }
 
 func TestRejectNonInstallableJavaLibrary(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myjar" is not configured to be compiled into dex`, `
 		apex {
 			name: "myapex",
@@ -7733,6 +7871,7 @@
 }
 
 func TestCarryRequiredModuleNames(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -7772,6 +7911,7 @@
 }
 
 func TestSymlinksFromApexToSystem(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
@@ -7926,6 +8066,7 @@
 }
 
 func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -7978,6 +8119,7 @@
 }
 
 func TestApexWithJniLibs(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8067,6 +8209,7 @@
 }
 
 func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8091,6 +8234,7 @@
 }
 
 func TestAppBundle(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8122,6 +8266,7 @@
 }
 
 func TestAppSetBundle(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8189,6 +8334,7 @@
 }
 
 func TestApexSetApksModuleAssignment(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_set {
 			name: "myapex",
@@ -8267,6 +8413,7 @@
 }
 
 func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
 		apex {
 			name: "myapex",
@@ -8283,6 +8430,7 @@
 }
 
 func TestUpdatableDefault_should_set_min_sdk_version(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
 		apex {
 			name: "myapex",
@@ -8298,6 +8446,7 @@
 }
 
 func TestUpdatable_should_not_set_generate_classpaths_proto(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"mysystemserverclasspathfragment" .* it must not set generate_classpaths_proto to false`, `
 		apex {
 			name: "myapex",
@@ -8342,8 +8491,10 @@
 }
 
 func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) {
+	t.Parallel()
 	preparer := java.FixtureConfigureApexBootJars("myapex:libfoo")
 	t.Run("prebuilt no source", func(t *testing.T) {
+		t.Parallel()
 		fragment := java.ApexVariantReference{
 			Apex:   proptools.StringPtr("myapex"),
 			Module: proptools.StringPtr("my-bootclasspath-fragment"),
@@ -8429,6 +8580,7 @@
 }
 
 func TestApexPermittedPackagesRules(t *testing.T) {
+	t.Parallel()
 	testcases := []struct {
 		name                 string
 		expectedError        string
@@ -8548,6 +8700,7 @@
 	}
 	for _, tc := range testcases {
 		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
 			rules := createBcpPermittedPackagesRules(tc.bcpPermittedPackages)
 			testBootJarPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules)
 		})
@@ -8555,6 +8708,7 @@
 }
 
 func TestTestFor(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8632,6 +8786,7 @@
 }
 
 func TestIndirectTestFor(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8692,6 +8847,7 @@
 }
 
 func TestTestForForLibInOtherApex(t *testing.T) {
+	t.Parallel()
 	// This case is only allowed for known overlapping APEXes, i.e. the ART APEXes.
 	_ = testApex(t, `
 		apex {
@@ -8747,6 +8903,7 @@
 }
 
 func TestApexSet(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_set {
 			name: "myapex",
@@ -8791,6 +8948,7 @@
 }
 
 func TestApexSet_NativeBridge(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex_set {
 			name: "myapex",
@@ -8815,6 +8973,7 @@
 }
 
 func TestNoStaticLinkingToStubsLib(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `.*required by "mylib" is a native library providing stub.*`, `
 		apex {
 			name: "myapex",
@@ -8852,6 +9011,7 @@
 }
 
 func TestApexKeysTxt(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8873,6 +9033,7 @@
 }
 
 func TestApexKeysTxtOverrides(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8917,6 +9078,7 @@
 }
 
 func TestAllowedFiles(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -8973,6 +9135,7 @@
 }
 
 func TestNonPreferredPrebuiltDependency(t *testing.T) {
+	t.Parallel()
 	testApex(t, `
 		apex {
 			name: "myapex",
@@ -9009,6 +9172,7 @@
 }
 
 func TestCompressedApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -9046,8 +9210,10 @@
 }
 
 func TestApexSet_ShouldRespectCompressedApexFlag(t *testing.T) {
+	t.Parallel()
 	for _, compressionEnabled := range []bool{true, false} {
 		t.Run(fmt.Sprintf("compressionEnabled=%v", compressionEnabled), func(t *testing.T) {
+			t.Parallel()
 			ctx := testApex(t, `
 				apex_set {
 					name: "com.company.android.myapex",
@@ -9070,6 +9236,7 @@
 }
 
 func TestPreferredPrebuiltSharedLibDep(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -9122,6 +9289,7 @@
 }
 
 func TestExcludeDependency(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -9172,6 +9340,7 @@
 }
 
 func TestPrebuiltStubLibDep(t *testing.T) {
+	t.Parallel()
 	bpBase := `
 		apex {
 			name: "myapex",
@@ -9264,8 +9433,10 @@
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			t.Parallel()
 			for _, otherApexEnabled := range test.otherApexEnabled {
 				t.Run("otherapex_enabled_"+otherApexEnabled, func(t *testing.T) {
+					t.Parallel()
 					ctx := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp)
 
 					type modAndMkEntries struct {
@@ -9333,6 +9504,7 @@
 }
 
 func TestApexJavaCoverage(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
@@ -9411,6 +9583,7 @@
 }
 
 func TestProhibitStaticExecutable(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `executable mybin is static`, `
 		apex {
 			name: "myapex",
@@ -9462,6 +9635,7 @@
 }
 
 func TestAndroidMk_DexpreoptBuiltInstalledForApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -9495,6 +9669,7 @@
 }
 
 func TestAndroidMk_RequiredModules(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -9534,6 +9709,7 @@
 }
 
 func TestAndroidMk_RequiredDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -9558,6 +9734,7 @@
 }
 
 func TestApexOutputFileProducer(t *testing.T) {
+	t.Parallel()
 	for _, tc := range []struct {
 		name          string
 		ref           string
@@ -9575,6 +9752,7 @@
 		},
 	} {
 		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
 			ctx := testApex(t, `
 					apex {
 						name: "myapex",
@@ -9606,6 +9784,7 @@
 }
 
 func TestSdkLibraryCanHaveHigherMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	preparer := android.GroupFixturePreparers(
 		PrepareForTestWithApexBuildComponents,
 		prepareForTestWithMyapex,
@@ -9618,6 +9797,7 @@
 
 	// Test java_sdk_library in bootclasspath_fragment may define higher min_sdk_version than the apex
 	t.Run("bootclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
+		t.Parallel()
 		preparer.RunTestWithBp(t, `
 			apex {
 				name: "myapex",
@@ -9674,6 +9854,7 @@
 
 	// Test java_sdk_library in systemserverclasspath_fragment may define higher min_sdk_version than the apex
 	t.Run("systemserverclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
+		t.Parallel()
 		preparer.RunTestWithBp(t, `
 			apex {
 				name: "myapex",
@@ -9723,6 +9904,7 @@
 	})
 
 	t.Run("bootclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
+		t.Parallel()
 		preparer.
 			RunTestWithBp(t, `
 				apex {
@@ -9761,6 +9943,7 @@
 	})
 
 	t.Run("systemserverclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
+		t.Parallel()
 		preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mysystemserverclasspathlib".*must set min_sdk_version`)).
 			RunTestWithBp(t, `
 				apex {
@@ -9811,6 +9994,7 @@
 }
 
 func TestApexStrictUpdtabilityLint(t *testing.T) {
+	t.Parallel()
 	bpTemplate := `
 		apex {
 			name: "myapex",
@@ -9882,6 +10066,7 @@
 
 	for _, testCase := range testCases {
 		t.Run(testCase.testCaseName, func(t *testing.T) {
+			t.Parallel()
 			fixtures := []android.FixturePreparer{}
 			baselineProperty := ""
 			if testCase.lintFileExists {
@@ -9922,6 +10107,7 @@
 
 // checks transtive deps of an apex coming from bootclasspath_fragment
 func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
@@ -9967,6 +10153,7 @@
 }
 
 func TestApexLintBcpFragmentSdkLibDeps(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
@@ -10018,6 +10205,7 @@
 
 // updatable apexes should propagate updatable=true to its apps
 func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
@@ -10047,6 +10235,7 @@
 }
 
 func TestTrimmedApex(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
@@ -10101,6 +10290,7 @@
 }
 
 func TestCannedFsConfig(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -10121,6 +10311,7 @@
 }
 
 func TestCannedFsConfig_HasCustomConfig(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -10143,6 +10334,7 @@
 }
 
 func TestStubLibrariesMultipleApexViolation(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		desc          string
 		hasStubs      bool
@@ -10217,6 +10409,7 @@
 }
 
 func TestFileSystemShouldSkipApexLibraries(t *testing.T) {
+	t.Parallel()
 	context := android.GroupFixturePreparers(
 		android.PrepareForIntegrationTestWithAndroid,
 		cc.PrepareForIntegrationTestWithCc,
@@ -10286,6 +10479,7 @@
 `
 
 func TestAconfigFilesJavaDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, apex_default_bp+`
 		apex {
 			name: "myapex",
@@ -10377,6 +10571,7 @@
 }
 
 func TestAconfigFilesJavaAndCcDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, apex_default_bp+`
 		apex {
 			name: "myapex",
@@ -10515,6 +10710,7 @@
 }
 
 func TestAconfigFilesRustDeps(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, apex_default_bp+`
 		apex {
 			name: "myapex",
@@ -10706,6 +10902,7 @@
 }
 
 func TestAconfigFilesOnlyMatchCurrentApex(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, apex_default_bp+`
 		apex {
 			name: "myapex",
@@ -10790,6 +10987,7 @@
 }
 
 func TestAconfigFilesRemoveDuplicates(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, apex_default_bp+`
 		apex {
 			name: "myapex",
@@ -10869,6 +11067,7 @@
 // Test that the boot jars come from the _selected_ apex prebuilt
 // RELEASE_APEX_CONTIRBUTIONS_* build flags will be used to select the correct prebuilt for a specific release config
 func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) {
+	t.Parallel()
 	checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
 		t.Helper()
 		s := ctx.ModuleForTests("dex_bootjars", "android_common")
@@ -11057,6 +11256,7 @@
 // Test that product packaging installs the selected mainline module (either source or a specific prebuilt)
 // RELEASE_APEX_CONTIRBUTIONS_* build flags will be used to select the correct prebuilt for a specific release config
 func TestInstallationRulesForMultipleApexPrebuilts(t *testing.T) {
+	t.Parallel()
 	// for a mainline module family, check that only the flagged soong module is visible to make
 	checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleName string, hiddenModuleNames []string) {
 		variation := func(moduleName string) string {
@@ -11202,6 +11402,7 @@
 
 // Test that product packaging installs the selected mainline module in workspaces withtout source mainline module
 func TestInstallationRulesForMultipleApexPrebuiltsWithoutSource(t *testing.T) {
+	t.Parallel()
 	// for a mainline module family, check that only the flagged soong module is visible to make
 	checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleNames []string, hiddenModuleNames []string) {
 		variation := func(moduleName string) string {
@@ -11309,6 +11510,7 @@
 }
 
 func TestAconfifDeclarationsValidation(t *testing.T) {
+	t.Parallel()
 	aconfigDeclarationLibraryString := func(moduleNames []string) (ret string) {
 		for _, moduleName := range moduleNames {
 			ret += fmt.Sprintf(`
@@ -11425,6 +11627,7 @@
 }
 
 func TestMultiplePrebuiltsWithSameBase(t *testing.T) {
+	t.Parallel()
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -11464,6 +11667,7 @@
 }
 
 func TestApexMinSdkVersionOverride(t *testing.T) {
+	t.Parallel()
 	checkMinSdkVersion := func(t *testing.T, module android.TestingModule, expectedMinSdkVersion string) {
 		args := module.Rule("apexRule").Args
 		optFlags := args["opt_flags"]
@@ -11540,6 +11744,7 @@
 }
 
 func TestOverrideApexWithPrebuiltApexPreferred(t *testing.T) {
+	t.Parallel()
 	context := android.GroupFixturePreparers(
 		android.PrepareForIntegrationTestWithAndroid,
 		PrepareForTestWithApexBuildComponents,
@@ -11575,6 +11780,7 @@
 }
 
 func TestUpdatableApexMinSdkVersionCurrent(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `"myapex" .*: updatable: updatable APEXes should not set min_sdk_version to current. Please use a finalized API level or a recognized in-development codename`, `
 		apex {
 			name: "myapex",
@@ -11592,6 +11798,7 @@
 }
 
 func TestPrebuiltStubNoinstall(t *testing.T) {
+	t.Parallel()
 	testFunc := func(t *testing.T, expectLibfooOnSystemLib bool, fs android.MockFS) {
 		result := android.GroupFixturePreparers(
 			prepareForApexTest,
@@ -11671,6 +11878,7 @@
 	`)
 
 	t.Run("prebuilt stub (without source): no install", func(t *testing.T) {
+		t.Parallel()
 		testFunc(
 			t,
 			/*expectLibfooOnSystemLib=*/ false,
@@ -11695,6 +11903,7 @@
 	`)
 
 	t.Run("prebuilt stub (with disabled source): no install", func(t *testing.T) {
+		t.Parallel()
 		testFunc(
 			t,
 			/*expectLibfooOnSystemLib=*/ false,
@@ -11710,6 +11919,7 @@
 }
 
 func TestSdkLibraryTransitiveClassLoaderContext(t *testing.T) {
+	t.Parallel()
 	// This test case tests that listing the impl lib instead of the top level java_sdk_library
 	// in libs of android_app and java_library does not lead to class loader context device/host
 	// path mismatch errors.
@@ -11819,6 +12029,7 @@
 
 // If an apex sets system_ext_specific: true, its systemserverclasspath libraries must set this property as well.
 func TestApexSSCPJarMustBeInSamePartitionAsApex(t *testing.T) {
+	t.Parallel()
 	testApexError(t, `foo is an apex systemserver jar, but its partition does not match the partition of its containing apex`, `
 		apex {
 			name: "myapex",
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index e44d3f5..71a8246 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -47,6 +47,7 @@
 )
 
 func TestBootclasspathFragments_FragmentDependency(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		// Configure some libraries in the art bootclasspath_fragment and platform_bootclasspath.
@@ -178,6 +179,7 @@
 }
 
 func TestBootclasspathFragmentInArtApex(t *testing.T) {
+	t.Parallel()
 	commonPreparer := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithArtApex,
@@ -298,6 +300,7 @@
 	}
 
 	t.Run("boot image files from source", func(t *testing.T) {
+		t.Parallel()
 		result := android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -329,6 +332,7 @@
 	})
 
 	t.Run("boot image files from source of override apex", func(t *testing.T) {
+		t.Parallel()
 		result := android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -349,6 +353,7 @@
 	})
 
 	t.Run("generate boot image profile even if dexpreopt is disabled", func(t *testing.T) {
+		t.Parallel()
 		result := android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -369,6 +374,7 @@
 	})
 
 	t.Run("boot image disable generate profile", func(t *testing.T) {
+		t.Parallel()
 		result := android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -387,6 +393,7 @@
 	})
 
 	t.Run("boot image files with preferred prebuilt", func(t *testing.T) {
+		t.Parallel()
 		result := android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -431,6 +438,7 @@
 	})
 
 	t.Run("source with inconsistency between config and contents", func(t *testing.T) {
+		t.Parallel()
 		android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -444,6 +452,7 @@
 	})
 
 	t.Run("prebuilt with inconsistency between config and contents", func(t *testing.T) {
+		t.Parallel()
 		android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -457,6 +466,7 @@
 	})
 
 	t.Run("preferred prebuilt with inconsistency between config and contents", func(t *testing.T) {
+		t.Parallel()
 		android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -473,6 +483,7 @@
 	})
 
 	t.Run("source preferred and prebuilt with inconsistency between config and contents", func(t *testing.T) {
+		t.Parallel()
 		android.GroupFixturePreparers(
 			commonPreparer,
 
@@ -491,6 +502,7 @@
 }
 
 func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
+	t.Parallel()
 	preparers := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithArtApex,
@@ -571,6 +583,7 @@
 	`
 
 	t.Run("disabled alternative APEX", func(t *testing.T) {
+		t.Parallel()
 		result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,"))
 
 		java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
@@ -614,6 +627,7 @@
 }
 
 func TestBootclasspathFragmentContentsNoName(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithMyapex,
@@ -722,6 +736,7 @@
 // TestBootclasspathFragment_HiddenAPIList checks to make sure that the correct parameters are
 // passed to the hiddenapi list tool.
 func TestBootclasspathFragment_HiddenAPIList(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithArtApex,
@@ -877,6 +892,7 @@
 // additional_stubs: ["android-non-updatable"] causes the source android-non-updatable modules to be
 // added to the hiddenapi list tool.
 func TestBootclasspathFragment_AndroidNonUpdatable_FromSource(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithArtApex,
@@ -1050,6 +1066,7 @@
 }
 
 func TestBootclasspathFragment_AndroidNonUpdatable_FromText(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithArtApex,
@@ -1217,6 +1234,7 @@
 // setting additional_stubs: ["android-non-updatable"] causes the prebuilt android-non-updatable
 // modules to be added to the hiddenapi list tool.
 func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		java.PrepareForTestWithDexpreopt,
@@ -1377,6 +1395,7 @@
 }
 
 func TestBootclasspathFragmentProtoContainsMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithBootclasspathFragment,
 		prepareForTestWithMyapex,
diff --git a/apex/classpath_element_test.go b/apex/classpath_element_test.go
index 9e1ac94..f8e8899 100644
--- a/apex/classpath_element_test.go
+++ b/apex/classpath_element_test.go
@@ -40,6 +40,7 @@
 var _ java.ClasspathElementContext = (*testClasspathElementContext)(nil)
 
 func TestCreateClasspathElements(t *testing.T) {
+	t.Parallel()
 	preparer := android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		prepareForTestWithArtApex,
@@ -240,6 +241,7 @@
 
 	// Verify that CreateClasspathElements works when given valid input.
 	t.Run("art:baz, art:quuz, my:bar, foo", func(t *testing.T) {
+		t.Parallel()
 		ctx := newCtx()
 		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, artQuuz, myBar, platformFoo}, []android.Module{artFragment, myFragment})
 		expectedElements := java.ClasspathElements{
@@ -252,6 +254,7 @@
 
 	// Verify that CreateClasspathElements detects when an apex has multiple fragments.
 	t.Run("multiple fragments for same apex", func(t *testing.T) {
+		t.Parallel()
 		ctx := newCtx()
 		elements := java.CreateClasspathElements(ctx, []android.Module{}, []android.Module{artFragment, artFragment})
 		android.FailIfNoMatchingErrors(t, "apex com.android.art has multiple fragments, art-bootclasspath-fragment{.*} and art-bootclasspath-fragment{.*}", ctx.errs)
@@ -261,6 +264,7 @@
 
 	// Verify that CreateClasspathElements detects when a library is in multiple fragments.
 	t.Run("library from multiple fragments", func(t *testing.T) {
+		t.Parallel()
 		ctx := newCtx()
 		elements := java.CreateClasspathElements(ctx, []android.Module{other}, []android.Module{artFragment, myFragment})
 		android.FailIfNoMatchingErrors(t, "library othersdklibrary{.*} is in two separate fragments, art-bootclasspath-fragment{.*} and mybootclasspath-fragment{.*}", ctx.errs)
@@ -271,6 +275,7 @@
 	// Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and
 	// are separated by a library from another fragment.
 	t.Run("discontiguous separated by fragment", func(t *testing.T) {
+		t.Parallel()
 		ctx := newCtx()
 		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, myBar, artQuuz, platformFoo}, []android.Module{artFragment, myFragment})
 		expectedElements := java.ClasspathElements{
@@ -285,6 +290,7 @@
 	// Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and
 	// are separated by a standalone library.
 	t.Run("discontiguous separated by library", func(t *testing.T) {
+		t.Parallel()
 		ctx := newCtx()
 		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, platformFoo, artQuuz, myBar}, []android.Module{artFragment, myFragment})
 		expectedElements := java.ClasspathElements{
@@ -300,6 +306,7 @@
 	// indicates it is from an apex the supplied fragments list does not contain a fragment for that
 	// apex.
 	t.Run("no fragment for apex", func(t *testing.T) {
+		t.Parallel()
 		ctx := newCtx()
 		elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, otherApexLibrary}, []android.Module{artFragment})
 		expectedElements := java.ClasspathElements{
diff --git a/apex/container_test.go b/apex/container_test.go
index d28b1a6..d1dfb9c 100644
--- a/apex/container_test.go
+++ b/apex/container_test.go
@@ -27,6 +27,7 @@
 }
 
 func TestApexDepsContainers(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForApexTest,
 		java.PrepareForTestWithJavaSdkLibraryFiles,
@@ -163,6 +164,7 @@
 }
 
 func TestNonUpdatableApexDepsContainers(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForApexTest,
 		java.PrepareForTestWithJavaSdkLibraryFiles,
@@ -277,6 +279,7 @@
 }
 
 func TestUpdatableAndNonUpdatableApexesIdenticalMinSdkVersion(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForApexTest,
 		java.PrepareForTestWithJavaSdkLibraryFiles,
diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go
index 4feade8..b51bb36 100644
--- a/apex/dexpreopt_bootjars_test.go
+++ b/apex/dexpreopt_bootjars_test.go
@@ -168,6 +168,7 @@
 }
 
 func TestDexpreoptBootJarsWithSourceArtApex(t *testing.T) {
+	t.Parallel()
 	ruleFile := "out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art"
 
 	expectedInputs := []string{
@@ -206,6 +207,7 @@
 // The only difference is that the ART profile should be deapexed from the prebuilt APEX. Other
 // inputs and outputs should be the same as above.
 func TestDexpreoptBootJarsWithPrebuiltArtApex(t *testing.T) {
+	t.Parallel()
 	ruleFile := "out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art"
 
 	expectedInputs := []string{
@@ -243,6 +245,7 @@
 
 // Changes to the boot.zip structure may break the ART APK scanner.
 func TestDexpreoptBootZip(t *testing.T) {
+	t.Parallel()
 	ruleFile := "boot.zip"
 
 	ctx := android.PathContextForTesting(android.TestArchConfig("", nil, "", nil))
@@ -271,6 +274,7 @@
 // Multiple ART apexes might exist in the tree.
 // The profile should correspond to the apex selected using release build flags
 func TestDexpreoptProfileWithMultiplePrebuiltArtApexes(t *testing.T) {
+	t.Parallel()
 	ruleFile := "out/soong/dexpreopt_arm64/dex_bootjars/android/system/framework/arm64/boot.art"
 	bp := `
 		// Platform.
@@ -425,6 +429,7 @@
 
 // Check that dexpreopt works with Google mainline prebuilts even in workspaces where source is missing
 func TestDexpreoptWithMainlinePrebuiltNoSource(t *testing.T) {
+	t.Parallel()
 	bp := `
 		// Platform.
 
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index f4da31e..9f9b0b4 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -36,6 +36,7 @@
 )
 
 func TestPlatformBootclasspath_Fragments(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		prepareForTestWithMyapex,
@@ -178,6 +179,7 @@
 //
 // TODO: Remove once all prebuilts use the filtered_... properties.
 func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		java.FixtureConfigureApexBootJars("myapex:foo"),
@@ -243,6 +245,7 @@
 }
 
 func TestPlatformBootclasspathDependencies(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		prepareForTestWithArtApex,
@@ -418,6 +421,7 @@
 // TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when
 // AlwaysUsePrebuiltSdk() returns true.
 func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		prepareForTestWithMyapex,
@@ -594,6 +598,7 @@
 // platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config
 // by setting generate_classpaths_proto property to false.
 func TestPlatformBootclasspath_IncludesRemainingApexJars(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		prepareForTestWithMyapex,
@@ -653,6 +658,7 @@
 }
 
 func TestBootJarNotInApex(t *testing.T) {
+	t.Parallel()
 	android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		PrepareForTestWithApexBuildComponents,
@@ -699,6 +705,7 @@
 }
 
 func TestBootFragmentNotInApex(t *testing.T) {
+	t.Parallel()
 	android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		PrepareForTestWithApexBuildComponents,
@@ -742,6 +749,7 @@
 }
 
 func TestNonBootJarInFragment(t *testing.T) {
+	t.Parallel()
 	android.GroupFixturePreparers(
 		prepareForTestWithPlatformBootclasspath,
 		PrepareForTestWithApexBuildComponents,
@@ -800,6 +808,7 @@
 
 // Skip bcp_fragment content validation of source apexes if prebuilts are active.
 func TestNonBootJarInPrebuilts(t *testing.T) {
+	t.Parallel()
 	testCases := []struct {
 		description               string
 		selectedApexContributions string
@@ -922,6 +931,7 @@
 
 // Source and prebuilt apex provide different set of boot jars
 func TestNonBootJarMissingInPrebuiltFragment(t *testing.T) {
+	t.Parallel()
 	bp := `
 		apex {
 			name: "myapex",
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index acb3649..7dbac5f 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -29,6 +29,7 @@
 )
 
 func TestSystemserverclasspathFragmentContents(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
@@ -118,6 +119,7 @@
 }
 
 func TestSystemserverclasspathFragmentNoGeneratedProto(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
@@ -171,6 +173,7 @@
 }
 
 func TestSystemServerClasspathFragmentWithContentNotInMake(t *testing.T) {
+	t.Parallel()
 	android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
@@ -222,6 +225,7 @@
 }
 
 func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
@@ -297,6 +301,7 @@
 }
 
 func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
@@ -380,6 +385,7 @@
 }
 
 func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
+	t.Parallel()
 	result := android.GroupFixturePreparers(
 		prepareForTestWithSystemserverclasspathFragment,
 		prepareForTestWithMyapex,
diff --git a/cc/cc.go b/cc/cc.go
index 791b1e5..e412528 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2345,6 +2345,10 @@
 		variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
 		if tag, ok := depTag.(libraryDependencyTag); ok {
 			tag.explicitlyVersioned = true
+			// depTag is an interface that contains a concrete non-pointer struct.  That makes the local
+			// tag variable a copy of the contents of depTag, and updating it doesn't change depTag.  Reassign
+			// the modified copy to depTag.
+			depTag = tag
 		} else {
 			panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
 		}
diff --git a/cc/library.go b/cc/library.go
index 91a09fa..1f21614 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1463,7 +1463,7 @@
 						headerAbiChecker.Exclude_symbol_tags,
 						currVendorVersion)
 				}
-				addLsdumpPath(string(tag) + ":" + llndkDump.String())
+				addLsdumpPath(ctx.Config(), string(tag)+":"+llndkDump.String())
 			} else if tag == apexLsdumpTag {
 				if apexVariantDump == nil {
 					apexVariantDump = library.linkApexSAbiDumpFiles(ctx,
@@ -1472,12 +1472,12 @@
 						headerAbiChecker.Exclude_symbol_tags,
 						currSdkVersion)
 				}
-				addLsdumpPath(string(tag) + ":" + apexVariantDump.String())
+				addLsdumpPath(ctx.Config(), string(tag)+":"+apexVariantDump.String())
 			} else {
 				if tag.dirName() == "" {
 					optInTags = append(optInTags, tag)
 				}
-				addLsdumpPath(string(tag) + ":" + implDump.String())
+				addLsdumpPath(ctx.Config(), string(tag)+":"+implDump.String())
 			}
 		}
 
diff --git a/cc/makevars.go b/cc/makevars.go
index c9352a4..f82e0e9 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -122,6 +122,7 @@
 	sort.Strings(exportedVendorPublicLibraries)
 	ctx.Strict("VENDOR_PUBLIC_LIBRARIES", strings.Join(exportedVendorPublicLibraries, " "))
 
+	lsdumpPaths := *lsdumpPaths(ctx.Config())
 	sort.Strings(lsdumpPaths)
 	ctx.Strict("LSDUMP_PATHS", strings.Join(lsdumpPaths, " "))
 
diff --git a/cc/sabi.go b/cc/sabi.go
index 2caf0d4..bc61b6c 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -22,10 +22,16 @@
 )
 
 var (
-	lsdumpPaths     []string
 	lsdumpPathsLock sync.Mutex
+	lsdumpKey       = android.NewOnceKey("lsdump")
 )
 
+func lsdumpPaths(config android.Config) *[]string {
+	return config.Once(lsdumpKey, func() any {
+		return &[]string{}
+	}).(*[]string)
+}
+
 type lsdumpTag string
 
 const (
@@ -291,8 +297,9 @@
 
 // Add an entry to the global list of lsdump. The list is exported to a Make variable by
 // `cc.makeVarsProvider`.
-func addLsdumpPath(lsdumpPath string) {
+func addLsdumpPath(config android.Config, lsdumpPath string) {
+	lsdumpPaths := lsdumpPaths(config)
 	lsdumpPathsLock.Lock()
 	defer lsdumpPathsLock.Unlock()
-	lsdumpPaths = append(lsdumpPaths, lsdumpPath)
+	*lsdumpPaths = append(*lsdumpPaths, lsdumpPath)
 }
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index f17a5de..ce72fed 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -66,6 +66,9 @@
 	ctx.RegisterModuleType("prebuilt_rfsa", PrebuiltRFSAFactory)
 	ctx.RegisterModuleType("prebuilt_renderscript_bitcode", PrebuiltRenderScriptBitcodeFactory)
 	ctx.RegisterModuleType("prebuilt_media_audio", PrebuiltMediaAudioFactory)
+	ctx.RegisterModuleType("prebuilt_voicepack", PrebuiltVoicepackFactory)
+	ctx.RegisterModuleType("prebuilt_bin", PrebuiltBinaryFactory)
+	ctx.RegisterModuleType("prebuilt_wallpaper", PrebuiltWallpaperFactory)
 
 	ctx.RegisterModuleType("prebuilt_defaults", defaultsFactory)
 
@@ -799,3 +802,33 @@
 	android.InitDefaultableModule(module)
 	return module
 }
+
+// prebuilt_voicepack installs voice pack files in <partition>/tts directory.
+func PrebuiltVoicepackFactory() android.Module {
+	module := &PrebuiltEtc{}
+	InitPrebuiltEtcModule(module, "tts")
+	// This module is device-only
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+	android.InitDefaultableModule(module)
+	return module
+}
+
+// prebuilt_bin installs files in <partition>/bin directory.
+func PrebuiltBinaryFactory() android.Module {
+	module := &PrebuiltEtc{}
+	InitPrebuiltEtcModule(module, "bin")
+	// This module is device-only
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+	android.InitDefaultableModule(module)
+	return module
+}
+
+// prebuilt_wallpaper installs image files in <partition>/wallpaper directory.
+func PrebuiltWallpaperFactory() android.Module {
+	module := &PrebuiltEtc{}
+	InitPrebuiltEtcModule(module, "wallpaper")
+	// This module is device-only
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+	android.InitDefaultableModule(module)
+	return module
+}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index ca0a7f7..97421c8 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -66,7 +66,7 @@
 	entries []string
 }
 
-type symlinkDefinition struct {
+type SymlinkDefinition struct {
 	Target *string
 	Name   *string
 }
@@ -111,7 +111,7 @@
 	Dirs proptools.Configurable[[]string]
 
 	// Symbolic links to be created under root with "ln -sf <target> <name>".
-	Symlinks []symlinkDefinition
+	Symlinks []SymlinkDefinition
 
 	// Seconds since unix epoch to override timestamps of file entries
 	Fake_timestamp *string
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index c903338..766176d 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -47,6 +47,7 @@
 }
 
 var fsGenStateOnceKey = android.NewOnceKey("FsGenState")
+var fsGenRemoveOverridesOnceKey = android.NewOnceKey("FsGenRemoveOverrides")
 
 // Map of partition module name to its partition that may be generated by Soong.
 // Note that it is not guaranteed that all modules returned by this function are successfully
@@ -79,6 +80,13 @@
 	soongGeneratedPartitions []string
 	// Mutex to protect the fsDeps
 	fsDepsMutex sync.Mutex
+	// Map of _all_ soong module names to their corresponding installation properties
+	moduleToInstallationProps map[string]installationProperties
+}
+
+type installationProperties struct {
+	Required  []string
+	Overrides []string
 }
 
 func newMultilibDeps() multilibDeps {
@@ -131,8 +139,9 @@
 					"update_engine_sideload":       defaultDepCandidateProps(ctx.Config()),
 				},
 				"vendor": &map[string]*depCandidateProps{
-					"fs_config_files_vendor": defaultDepCandidateProps(ctx.Config()),
-					"fs_config_dirs_vendor":  defaultDepCandidateProps(ctx.Config()),
+					"fs_config_files_vendor":                               defaultDepCandidateProps(ctx.Config()),
+					"fs_config_dirs_vendor":                                defaultDepCandidateProps(ctx.Config()),
+					generatedModuleName(ctx.Config(), "vendor-build.prop"): defaultDepCandidateProps(ctx.Config()),
 				},
 				"odm":     newMultilibDeps(),
 				"product": newMultilibDeps(),
@@ -147,8 +156,9 @@
 					"com.android.vndk.v34": defaultDepCandidateProps(ctx.Config()),
 				},
 			},
-			soongGeneratedPartitions: generatedPartitions,
-			fsDepsMutex:              sync.Mutex{},
+			soongGeneratedPartitions:  generatedPartitions,
+			fsDepsMutex:               sync.Mutex{},
+			moduleToInstallationProps: map[string]installationProperties{},
 		}
 	}).(*FsGenState)
 }
@@ -193,6 +203,16 @@
 		}
 		fsGenState.fsDepsMutex.Unlock()
 	}
+	// store the map of module to (required,overrides) even if the module is not in PRODUCT_PACKAGES.
+	// the module might be installed transitively.
+	if m.Target().Os.Class == android.Device && m.Enabled(mctx) && m.ExportedToMake() {
+		fsGenState.fsDepsMutex.Lock()
+		fsGenState.moduleToInstallationProps[m.Name()] = installationProperties{
+			Required:  m.RequiredModuleNames(mctx),
+			Overrides: m.Overrides(),
+		}
+		fsGenState.fsDepsMutex.Unlock()
+	}
 }
 
 type depsStruct struct {
@@ -231,6 +251,7 @@
 }
 
 func setDepsMutator(mctx android.BottomUpMutatorContext) {
+	removeOverriddenDeps(mctx)
 	fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
 	fsDeps := fsGenState.fsDeps
 	soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions)
@@ -243,6 +264,47 @@
 	}
 }
 
+// removeOverriddenDeps collects PRODUCT_PACKAGES and (transitive) required deps.
+// it then removes any modules which appear in `overrides` of the above list.
+func removeOverriddenDeps(mctx android.BottomUpMutatorContext) {
+	mctx.Config().Once(fsGenRemoveOverridesOnceKey, func() interface{} {
+		fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+		fsDeps := fsGenState.fsDeps
+		overridden := map[string]bool{}
+		allDeps := []string{}
+
+		// Step 1: Initialization: Append PRODUCT_PACKAGES to the queue
+		for _, fsDep := range fsDeps {
+			for depName, _ := range *fsDep {
+				allDeps = append(allDeps, depName)
+			}
+		}
+
+		// Step 2: Process the queue, and add required modules to the queue.
+		i := 0
+		for {
+			if i == len(allDeps) {
+				break
+			}
+			depName := allDeps[i]
+			for _, overrides := range fsGenState.moduleToInstallationProps[depName].Overrides {
+				overridden[overrides] = true
+			}
+			// add required dep to the queue.
+			allDeps = append(allDeps, fsGenState.moduleToInstallationProps[depName].Required...)
+			i += 1
+		}
+
+		// Step 3: Delete all the overridden modules.
+		for overridden, _ := range overridden {
+			for partition, _ := range fsDeps {
+				delete(*fsDeps[partition], overridden)
+			}
+		}
+		return nil
+	})
+}
+
 func generateDepStruct(deps map[string]*depCandidateProps) *packagingPropsStruct {
 	depsStruct := packagingPropsStruct{}
 	for depName, depProps := range deps {
@@ -387,6 +449,17 @@
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
 	case "vendor":
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
+		fsProps.Symlinks = []filesystem.SymlinkDefinition{
+			filesystem.SymlinkDefinition{
+				Target: proptools.StringPtr("/odm"),
+				Name:   proptools.StringPtr("vendor/odm"),
+			},
+			filesystem.SymlinkDefinition{
+				Target: proptools.StringPtr("/vendor_dlkm/lib/modules"),
+				Name:   proptools.StringPtr("vendor/lib/modules"),
+			},
+		}
+		fsProps.Base_dir = proptools.StringPtr("vendor")
 	}
 }
 
@@ -409,6 +482,25 @@
 		module = ctx.CreateModule(filesystem.FilesystemFactory, baseProps, fsProps)
 	}
 	module.HideFromMake()
+	if partitionType == "vendor" {
+		// Create a build prop for vendor
+		vendorBuildProps := &struct {
+			Name           *string
+			Vendor         *bool
+			Stem           *string
+			Product_config *string
+		}{
+			Name:           proptools.StringPtr(generatedModuleName(ctx.Config(), "vendor-build.prop")),
+			Vendor:         proptools.BoolPtr(true),
+			Stem:           proptools.StringPtr("build.prop"),
+			Product_config: proptools.StringPtr(":product_config"),
+		}
+		vendorBuildProp := ctx.CreateModule(
+			android.BuildPropFactory,
+			vendorBuildProps,
+		)
+		vendorBuildProp.HideFromMake()
+	}
 	return true
 }
 
@@ -563,6 +655,9 @@
 	if !fsTypeSupported {
 		return ""
 	}
+	if partitionType == "vendor" {
+		return "" // TODO: Handle struct props
+	}
 
 	baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
 	deps := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps[partitionType]
diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go
index 484cc38..199eaad 100644
--- a/fsgen/filesystem_creator_test.go
+++ b/fsgen/filesystem_creator_test.go
@@ -217,3 +217,39 @@
 		"//c/d:bar",
 	)
 }
+
+func TestRemoveOverriddenModulesFromDeps(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		android.PrepareForIntegrationTestWithAndroid,
+		android.PrepareForTestWithAndroidBuildComponents,
+		android.PrepareForTestWithAllowMissingDependencies,
+		prepareForTestWithFsgenBuildComponents,
+		java.PrepareForTestWithJavaBuildComponents,
+		android.FixtureMergeMockFs(android.MockFS{
+			"external/avb/test/data/testkey_rsa4096.pem": nil,
+			"build/soong/fsgen/Android.bp": []byte(`
+			soong_filesystem_creator {
+				name: "foo",
+			}
+			`),
+		}),
+		android.FixtureModifyConfig(func(config android.Config) {
+			config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"libfoo", "libbar"}
+		}),
+	).RunTestWithBp(t, `
+java_library {
+	name: "libfoo",
+}
+java_library {
+	name: "libbar",
+	required: ["libbaz"],
+}
+java_library {
+	name: "libbaz",
+	overrides: ["libfoo"], // overrides libfoo
+}
+	`)
+	resolvedSystemDeps := result.TestContext.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps["system"]
+	_, libFooInDeps := (*resolvedSystemDeps)["libfoo"]
+	android.AssertBoolEquals(t, "libfoo should not appear in deps because it has been overridden by libbaz. The latter is a required dep of libbar, which is listed in PRODUCT_PACKAGES", false, libFooInDeps)
+}
diff --git a/golang/golang.go b/golang/golang.go
index 6ee924f..d33f5e0 100644
--- a/golang/golang.go
+++ b/golang/golang.go
@@ -47,7 +47,7 @@
 func goPackageModuleFactory() android.Module {
 	module := &GoPackage{}
 	module.AddProperties(module.Properties()...)
-	android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst)
+	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
 	return module
 }
 
@@ -74,7 +74,7 @@
 func goBinaryModuleFactory() android.Module {
 	module := &GoBinary{}
 	module.AddProperties(module.Properties()...)
-	android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst)
+	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
 	return module
 }
 
diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py
index df9e98d..e0686ed 100644
--- a/scripts/gen_build_prop.py
+++ b/scripts/gen_build_prop.py
@@ -524,7 +524,6 @@
 
   build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
 
-'''
 def build_vendor_prop(args):
   config = args.config
 
@@ -541,7 +540,6 @@
     ]
 
   build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
-'''
 
 def build_product_prop(args):
   config = args.config
@@ -608,8 +606,8 @@
         build_odm_prop(args)
       case "product":
         build_product_prop(args)
-      # case "vendor":  # NOT IMPLEMENTED
-      #  build_vendor_prop(args)
+      case "vendor":
+        build_vendor_prop(args)
       case _:
         sys.exit(f"not supported partition {args.partition}")
 
diff --git a/ui/build/soong.go b/ui/build/soong.go
index cd20a4a..e6d01dd 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -287,6 +287,15 @@
 	ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap")
 	defer ctx.EndTrace()
 
+	st := ctx.Status.StartTool()
+	defer st.Finish()
+	st.SetTotalActions(1)
+	action := &status.Action{
+		Description: "bootstrap blueprint",
+		Outputs:     []string{"bootstrap blueprint"},
+	}
+	st.StartAction(action)
+
 	// Clean up some files for incremental builds across incompatible changes.
 	bootstrapEpochCleanup(ctx, config)
 
@@ -395,8 +404,17 @@
 	// since `bootstrap.ninja` is regenerated unconditionally, we ignore the deps, i.e. little
 	// reason to write a `bootstrap.ninja.d` file
 	_, err := bootstrap.RunBlueprint(blueprintArgs, bootstrap.DoEverything, blueprintCtx, blueprintConfig)
+
+	result := status.ActionResult{
+		Action: action,
+	}
 	if err != nil {
-		ctx.Fatal(err)
+		result.Error = err
+		result.Output = err.Error()
+	}
+	st.FinishAction(result)
+	if err != nil {
+		ctx.Fatalf("bootstrap failed")
 	}
 }
 
@@ -792,8 +810,10 @@
 						changedGlobNameMutex.Lock()
 						defer changedGlobNameMutex.Unlock()
 						changedGlobName = result.Pattern
-						if len(result.Excludes) > 0 {
-							changedGlobName += " (excluding " + strings.Join(result.Excludes, ", ") + ")"
+						if len(result.Excludes) > 2 {
+							changedGlobName += fmt.Sprintf(" (excluding %d other patterns)", len(result.Excludes))
+						} else if len(result.Excludes) > 0 {
+							changedGlobName += " (excluding " + strings.Join(result.Excludes, " and ") + ")"
 						}
 					}
 				}
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index b75f572..05b23d7 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -425,6 +425,8 @@
 	// Note that not all changed environment variables result in analysis retriggering.
 	// If there was no previous build, this list will be empty.
 	ChangedEnvironmentVariable []string `protobuf:"bytes,34,rep,name=changed_environment_variable,json=changedEnvironmentVariable" json:"changed_environment_variable,omitempty"`
+	// Metrics related to optimized builds.
+	OptimizedBuildMetrics *OptimizedBuildMetrics `protobuf:"bytes,35,opt,name=optimized_build_metrics,json=optimizedBuildMetrics" json:"optimized_build_metrics,omitempty"`
 }
 
 // Default values for MetricsBase fields.
@@ -706,6 +708,13 @@
 	return nil
 }
 
+func (x *MetricsBase) GetOptimizedBuildMetrics() *OptimizedBuildMetrics {
+	if x != nil {
+		return x.OptimizedBuildMetrics
+	}
+	return nil
+}
+
 type BuildConfig struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -1846,12 +1855,229 @@
 	return ""
 }
 
+type OptimizedBuildMetrics struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The total time spent analyzing what/how to optimize everything.
+	AnalysisPerf *PerfInfo `protobuf:"bytes,1,opt,name=analysis_perf,json=analysisPerf" json:"analysis_perf,omitempty"`
+	// The total time spent packaging artifacts.
+	PackagingPerf *PerfInfo `protobuf:"bytes,2,opt,name=packaging_perf,json=packagingPerf" json:"packaging_perf,omitempty"`
+	// Information for a single target (e.g. general-tests).
+	TargetResult []*OptimizedBuildMetrics_TargetOptimizationResult `protobuf:"bytes,3,rep,name=target_result,json=targetResult" json:"target_result,omitempty"`
+}
+
+func (x *OptimizedBuildMetrics) Reset() {
+	*x = OptimizedBuildMetrics{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_metrics_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OptimizedBuildMetrics) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OptimizedBuildMetrics) ProtoMessage() {}
+
+func (x *OptimizedBuildMetrics) ProtoReflect() protoreflect.Message {
+	mi := &file_metrics_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OptimizedBuildMetrics.ProtoReflect.Descriptor instead.
+func (*OptimizedBuildMetrics) Descriptor() ([]byte, []int) {
+	return file_metrics_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *OptimizedBuildMetrics) GetAnalysisPerf() *PerfInfo {
+	if x != nil {
+		return x.AnalysisPerf
+	}
+	return nil
+}
+
+func (x *OptimizedBuildMetrics) GetPackagingPerf() *PerfInfo {
+	if x != nil {
+		return x.PackagingPerf
+	}
+	return nil
+}
+
+func (x *OptimizedBuildMetrics) GetTargetResult() []*OptimizedBuildMetrics_TargetOptimizationResult {
+	if x != nil {
+		return x.TargetResult
+	}
+	return nil
+}
+
+type OptimizedBuildMetrics_TargetOptimizationResult struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Target name (e.g. general-tests).
+	Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	// Whether or not this target was optimized.
+	Optimized *bool `protobuf:"varint,2,opt,name=optimized" json:"optimized,omitempty"`
+	// Reasoning for why the target wasn't optimized if it wasn't
+	OptimizationRationale *string `protobuf:"bytes,3,opt,name=optimization_rationale,json=optimizationRationale" json:"optimization_rationale,omitempty"`
+	// Time spent packaging this specific target (if it was optimized).
+	PackagingPerf *PerfInfo `protobuf:"bytes,4,opt,name=packaging_perf,json=packagingPerf" json:"packaging_perf,omitempty"`
+	// Information for each different artifact produced by this target (if it
+	// was optimized).
+	OutputArtifact []*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact `protobuf:"bytes,5,rep,name=output_artifact,json=outputArtifact" json:"output_artifact,omitempty"`
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) Reset() {
+	*x = OptimizedBuildMetrics_TargetOptimizationResult{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_metrics_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OptimizedBuildMetrics_TargetOptimizationResult) ProtoMessage() {}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) ProtoReflect() protoreflect.Message {
+	mi := &file_metrics_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OptimizedBuildMetrics_TargetOptimizationResult.ProtoReflect.Descriptor instead.
+func (*OptimizedBuildMetrics_TargetOptimizationResult) Descriptor() ([]byte, []int) {
+	return file_metrics_proto_rawDescGZIP(), []int{16, 0}
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) GetName() string {
+	if x != nil && x.Name != nil {
+		return *x.Name
+	}
+	return ""
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) GetOptimized() bool {
+	if x != nil && x.Optimized != nil {
+		return *x.Optimized
+	}
+	return false
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) GetOptimizationRationale() string {
+	if x != nil && x.OptimizationRationale != nil {
+		return *x.OptimizationRationale
+	}
+	return ""
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) GetPackagingPerf() *PerfInfo {
+	if x != nil {
+		return x.PackagingPerf
+	}
+	return nil
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult) GetOutputArtifact() []*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact {
+	if x != nil {
+		return x.OutputArtifact
+	}
+	return nil
+}
+
+type OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Artifact file name (e.g. general-tests.zip)
+	Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	// Size of the file.
+	Size *int64 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"`
+	// Lists of modules packaged into this artifact.
+	IncludedModules []string `protobuf:"bytes,3,rep,name=included_modules,json=includedModules" json:"included_modules,omitempty"`
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) Reset() {
+	*x = OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_metrics_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) ProtoMessage() {}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) ProtoReflect() protoreflect.Message {
+	mi := &file_metrics_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact.ProtoReflect.Descriptor instead.
+func (*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) Descriptor() ([]byte, []int) {
+	return file_metrics_proto_rawDescGZIP(), []int{16, 0, 0}
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) GetName() string {
+	if x != nil && x.Name != nil {
+		return *x.Name
+	}
+	return ""
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) GetSize() int64 {
+	if x != nil && x.Size != nil {
+		return *x.Size
+	}
+	return 0
+}
+
+func (x *OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact) GetIncludedModules() []string {
+	if x != nil {
+		return x.IncludedModules
+	}
+	return nil
+}
+
 var File_metrics_proto protoreflect.FileDescriptor
 
 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, 0xcc, 0x0f, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x72, 0x69, 0x63, 0x73, 0x22, 0xb0, 0x10, 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,
@@ -1969,217 +2195,267 @@
 	0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
 	0x65, 0x18, 0x22, 0x20, 0x03, 0x28, 0x09, 0x52, 0x1a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64,
 	0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61,
-	0x62, 0x6c, 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, 0x8a, 0x04, 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, 0x12,
-	0x79, 0x0a, 0x18, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5f,
-	0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28,
-	0x0e, 0x32, 0x36, 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, 0x2e, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c,
-	0x69, 0x73, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08, 0x4e, 0x4f, 0x54, 0x5f, 0x55,
-	0x53, 0x45, 0x44, 0x52, 0x15, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74,
-	0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x74, 0x0a, 0x15, 0x4e, 0x69,
-	0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x10,
-	0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x49, 0x4e, 0x4a, 0x41, 0x5f, 0x4c, 0x4f, 0x47, 0x10, 0x01,
-	0x12, 0x16, 0x0a, 0x12, 0x45, 0x56, 0x45, 0x4e, 0x4c, 0x59, 0x5f, 0x44, 0x49, 0x53, 0x54, 0x52,
-	0x49, 0x42, 0x55, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x58, 0x54, 0x45,
-	0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x48,
-	0x49, 0x4e, 0x54, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x53, 0x4f, 0x4f, 0x4e, 0x47, 0x10, 0x04,
-	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, 0x61,
-	0x0a, 0x0c, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x12, 0x12,
-	0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x74, 0x69,
-	0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03,
-	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, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75,
-	0x6e, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70,
-	0x73, 0x22, 0x64, 0x0a, 0x10, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
-	0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x63, 0x6f, 0x75,
-	0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x6f,
+	0x62, 0x6c, 0x65, 0x12, 0x62, 0x0a, 0x17, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64,
+	0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x23,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69,
+	0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d,
+	0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x52, 0x15, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64,
+	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 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, 0x8a, 0x04, 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, 0x12, 0x79, 0x0a, 0x18, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x5f, 0x77, 0x65, 0x69,
+	0x67, 0x68, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
+	0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 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, 0x2e, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69,
+	0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x08, 0x4e,
+	0x4f, 0x54, 0x5f, 0x55, 0x53, 0x45, 0x44, 0x52, 0x15, 0x6e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65,
+	0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x74,
+	0x0a, 0x15, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x73,
+	0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x4e, 0x4f, 0x54, 0x5f, 0x55,
+	0x53, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x49, 0x4e, 0x4a, 0x41, 0x5f, 0x4c,
+	0x4f, 0x47, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x56, 0x45, 0x4e, 0x4c, 0x59, 0x5f, 0x44,
+	0x49, 0x53, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d,
+	0x45, 0x58, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x03, 0x12,
+	0x13, 0x0a, 0x0f, 0x48, 0x49, 0x4e, 0x54, 0x5f, 0x46, 0x52, 0x4f, 0x4d, 0x5f, 0x53, 0x4f, 0x4f,
+	0x4e, 0x47, 0x10, 0x04, 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, 0x61, 0x0a, 0x0c, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
+	0x72, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73,
+	0x18, 0x02, 0x20, 0x03, 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, 0x50, 0x65, 0x72,
+	0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x06, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x73, 0x22, 0x64, 0x0a, 0x10, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75,
+	0x6e, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a,
+	0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 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, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65,
+	0x72, 0x52, 0x08, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x22, 0x37, 0x0a, 0x0b, 0x50,
+	0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 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, 0x50, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63,
-	0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x22, 0x37, 0x0a, 0x0b, 0x50, 0x65, 0x72, 0x66, 0x43,
-	0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
-	0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 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, 0x94, 0x03, 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, 0x12, 0x46, 0x0a, 0x0d, 0x70, 0x65, 0x72, 0x66, 0x5f, 0x63, 0x6f,
-	0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 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, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x52,
-	0x0c, 0x70, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 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, 0x22,
-	0x8a, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68,
-	0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f,
-	0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x04, 0x52, 0x11, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69,
-	0x63, 0x72, 0x6f, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c,
-	0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f,
-	0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61,
-	0x6c, 0x50, 0x61, 0x74, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12,
-	0x41, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68,
-	0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62,
-	0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4a, 0x6f, 0x62,
-	0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61,
-	0x74, 0x68, 0x12, 0x48, 0x0a, 0x11, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x69,
-	0x6e, 0x67, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
-	0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x73, 0x2e, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x6c, 0x6f, 0x6e,
-	0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x4a, 0x6f, 0x62, 0x73, 0x22, 0x62, 0x0a, 0x07,
-	0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x6c, 0x61, 0x70, 0x73,
-	0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69, 0x6d,
-	0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6a, 0x6f, 0x62, 0x5f, 0x64,
-	0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0e, 0x6a, 0x6f, 0x62, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	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, 0x94, 0x03, 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, 0x12, 0x46, 0x0a, 0x0d, 0x70, 0x65, 0x72,
+	0x66, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x21, 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, 0x43, 0x6f, 0x75, 0x6e, 0x74,
+	0x65, 0x72, 0x73, 0x52, 0x0c, 0x70, 0x65, 0x72, 0x66, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72,
+	0x73, 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, 0x22, 0x8a, 0x02, 0x0a, 0x10, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c,
+	0x50, 0x61, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x6c, 0x61, 0x70,
+	0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x54, 0x69,
+	0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x63, 0x72, 0x69, 0x74,
+	0x69, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d,
+	0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x63, 0x72, 0x69,
+	0x74, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63,
+	0x72, 0x6f, 0x73, 0x12, 0x41, 0x0a, 0x0d, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f,
+	0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x6f,
+	0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
+	0x2e, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0c, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63,
+	0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x48, 0x0a, 0x11, 0x6c, 0x6f, 0x6e, 0x67, 0x5f, 0x72,
+	0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x1c, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f,
+	0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52,
+	0x0f, 0x6c, 0x6f, 0x6e, 0x67, 0x52, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x4a, 0x6f, 0x62, 0x73,
+	0x22, 0x62, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2e, 0x0a, 0x13, 0x65,
+	0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x69, 0x63, 0x72,
+	0x6f, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65,
+	0x64, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6a,
+	0x6f, 0x62, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6a, 0x6f, 0x62, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb9, 0x05, 0x0a, 0x15, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a,
+	0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x42,
+	0x0a, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x66, 0x18,
+	0x01, 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, 0x0c, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x50, 0x65,
+	0x72, 0x66, 0x12, 0x44, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f,
+	0x70, 0x65, 0x72, 0x66, 0x18, 0x02, 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, 0x0d, 0x70, 0x61, 0x63, 0x6b, 0x61,
+	0x67, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x66, 0x12, 0x68, 0x0a, 0x0d, 0x74, 0x61, 0x72, 0x67,
+	0x65, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x43, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42,
+	0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67,
+	0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x52, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x1a, 0xab, 0x03, 0x0a, 0x18, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x70, 0x74,
+	0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65,
+	0x64, 0x12, 0x35, 0x0a, 0x16, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x15, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x65, 0x12, 0x44, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b,
+	0x61, 0x67, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x65, 0x72, 0x66, 0x18, 0x04, 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,
+	0x0d, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x66, 0x12, 0x7b,
+	0x0a, 0x0f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63,
+	0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x52, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
+	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4f, 0x70,
+	0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x73, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69,
+	0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4f, 0x75, 0x74,
+	0x70, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x0e, 0x6f, 0x75, 0x74,
+	0x70, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x1a, 0x63, 0x0a, 0x0e, 0x4f,
+	0x75, 0x74, 0x70, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65,
+	0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52,
+	0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 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,
@@ -2198,29 +2474,32 @@
 }
 
 var file_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
-var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
+var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 19)
 var file_metrics_proto_goTypes = []interface{}{
-	(MetricsBase_BuildVariant)(0),          // 0: soong_build_metrics.MetricsBase.BuildVariant
-	(MetricsBase_Arch)(0),                  // 1: soong_build_metrics.MetricsBase.Arch
-	(BuildConfig_NinjaWeightListSource)(0), // 2: soong_build_metrics.BuildConfig.NinjaWeightListSource
-	(ModuleTypeInfo_BuildSystem)(0),        // 3: soong_build_metrics.ModuleTypeInfo.BuildSystem
-	(ExpConfigFetcher_ConfigStatus)(0),     // 4: soong_build_metrics.ExpConfigFetcher.ConfigStatus
-	(*MetricsBase)(nil),                    // 5: soong_build_metrics.MetricsBase
-	(*BuildConfig)(nil),                    // 6: soong_build_metrics.BuildConfig
-	(*SystemResourceInfo)(nil),             // 7: soong_build_metrics.SystemResourceInfo
-	(*PerfInfo)(nil),                       // 8: soong_build_metrics.PerfInfo
-	(*PerfCounters)(nil),                   // 9: soong_build_metrics.PerfCounters
-	(*PerfCounterGroup)(nil),               // 10: soong_build_metrics.PerfCounterGroup
-	(*PerfCounter)(nil),                    // 11: soong_build_metrics.PerfCounter
-	(*ProcessResourceInfo)(nil),            // 12: soong_build_metrics.ProcessResourceInfo
-	(*ModuleTypeInfo)(nil),                 // 13: soong_build_metrics.ModuleTypeInfo
-	(*CriticalUserJourneyMetrics)(nil),     // 14: soong_build_metrics.CriticalUserJourneyMetrics
-	(*CriticalUserJourneysMetrics)(nil),    // 15: soong_build_metrics.CriticalUserJourneysMetrics
-	(*SoongBuildMetrics)(nil),              // 16: soong_build_metrics.SoongBuildMetrics
-	(*ExpConfigFetcher)(nil),               // 17: soong_build_metrics.ExpConfigFetcher
-	(*MixedBuildsInfo)(nil),                // 18: soong_build_metrics.MixedBuildsInfo
-	(*CriticalPathInfo)(nil),               // 19: soong_build_metrics.CriticalPathInfo
-	(*JobInfo)(nil),                        // 20: soong_build_metrics.JobInfo
+	(MetricsBase_BuildVariant)(0),                          // 0: soong_build_metrics.MetricsBase.BuildVariant
+	(MetricsBase_Arch)(0),                                  // 1: soong_build_metrics.MetricsBase.Arch
+	(BuildConfig_NinjaWeightListSource)(0),                 // 2: soong_build_metrics.BuildConfig.NinjaWeightListSource
+	(ModuleTypeInfo_BuildSystem)(0),                        // 3: soong_build_metrics.ModuleTypeInfo.BuildSystem
+	(ExpConfigFetcher_ConfigStatus)(0),                     // 4: soong_build_metrics.ExpConfigFetcher.ConfigStatus
+	(*MetricsBase)(nil),                                    // 5: soong_build_metrics.MetricsBase
+	(*BuildConfig)(nil),                                    // 6: soong_build_metrics.BuildConfig
+	(*SystemResourceInfo)(nil),                             // 7: soong_build_metrics.SystemResourceInfo
+	(*PerfInfo)(nil),                                       // 8: soong_build_metrics.PerfInfo
+	(*PerfCounters)(nil),                                   // 9: soong_build_metrics.PerfCounters
+	(*PerfCounterGroup)(nil),                               // 10: soong_build_metrics.PerfCounterGroup
+	(*PerfCounter)(nil),                                    // 11: soong_build_metrics.PerfCounter
+	(*ProcessResourceInfo)(nil),                            // 12: soong_build_metrics.ProcessResourceInfo
+	(*ModuleTypeInfo)(nil),                                 // 13: soong_build_metrics.ModuleTypeInfo
+	(*CriticalUserJourneyMetrics)(nil),                     // 14: soong_build_metrics.CriticalUserJourneyMetrics
+	(*CriticalUserJourneysMetrics)(nil),                    // 15: soong_build_metrics.CriticalUserJourneysMetrics
+	(*SoongBuildMetrics)(nil),                              // 16: soong_build_metrics.SoongBuildMetrics
+	(*ExpConfigFetcher)(nil),                               // 17: soong_build_metrics.ExpConfigFetcher
+	(*MixedBuildsInfo)(nil),                                // 18: soong_build_metrics.MixedBuildsInfo
+	(*CriticalPathInfo)(nil),                               // 19: soong_build_metrics.CriticalPathInfo
+	(*JobInfo)(nil),                                        // 20: soong_build_metrics.JobInfo
+	(*OptimizedBuildMetrics)(nil),                          // 21: soong_build_metrics.OptimizedBuildMetrics
+	(*OptimizedBuildMetrics_TargetOptimizationResult)(nil), // 22: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult
+	(*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact)(nil), // 23: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact
 }
 var file_metrics_proto_depIdxs = []int32{
 	0,  // 0: soong_build_metrics.MetricsBase.target_build_variant:type_name -> soong_build_metrics.MetricsBase.BuildVariant
@@ -2238,24 +2517,30 @@
 	8,  // 12: soong_build_metrics.MetricsBase.bazel_runs:type_name -> soong_build_metrics.PerfInfo
 	17, // 13: soong_build_metrics.MetricsBase.exp_config_fetcher:type_name -> soong_build_metrics.ExpConfigFetcher
 	19, // 14: soong_build_metrics.MetricsBase.critical_path_info:type_name -> soong_build_metrics.CriticalPathInfo
-	2,  // 15: soong_build_metrics.BuildConfig.ninja_weight_list_source:type_name -> soong_build_metrics.BuildConfig.NinjaWeightListSource
-	12, // 16: soong_build_metrics.PerfInfo.processes_resource_info:type_name -> soong_build_metrics.ProcessResourceInfo
-	10, // 17: soong_build_metrics.PerfCounters.groups:type_name -> soong_build_metrics.PerfCounterGroup
-	11, // 18: soong_build_metrics.PerfCounterGroup.counters:type_name -> soong_build_metrics.PerfCounter
-	3,  // 19: soong_build_metrics.ModuleTypeInfo.build_system:type_name -> soong_build_metrics.ModuleTypeInfo.BuildSystem
-	5,  // 20: soong_build_metrics.CriticalUserJourneyMetrics.metrics:type_name -> soong_build_metrics.MetricsBase
-	14, // 21: soong_build_metrics.CriticalUserJourneysMetrics.cujs:type_name -> soong_build_metrics.CriticalUserJourneyMetrics
-	8,  // 22: soong_build_metrics.SoongBuildMetrics.events:type_name -> soong_build_metrics.PerfInfo
-	18, // 23: soong_build_metrics.SoongBuildMetrics.mixed_builds_info:type_name -> soong_build_metrics.MixedBuildsInfo
-	9,  // 24: soong_build_metrics.SoongBuildMetrics.perf_counters:type_name -> soong_build_metrics.PerfCounters
-	4,  // 25: soong_build_metrics.ExpConfigFetcher.status:type_name -> soong_build_metrics.ExpConfigFetcher.ConfigStatus
-	20, // 26: soong_build_metrics.CriticalPathInfo.critical_path:type_name -> soong_build_metrics.JobInfo
-	20, // 27: soong_build_metrics.CriticalPathInfo.long_running_jobs:type_name -> soong_build_metrics.JobInfo
-	28, // [28:28] is the sub-list for method output_type
-	28, // [28:28] is the sub-list for method input_type
-	28, // [28:28] is the sub-list for extension type_name
-	28, // [28:28] is the sub-list for extension extendee
-	0,  // [0:28] is the sub-list for field type_name
+	21, // 15: soong_build_metrics.MetricsBase.optimized_build_metrics:type_name -> soong_build_metrics.OptimizedBuildMetrics
+	2,  // 16: soong_build_metrics.BuildConfig.ninja_weight_list_source:type_name -> soong_build_metrics.BuildConfig.NinjaWeightListSource
+	12, // 17: soong_build_metrics.PerfInfo.processes_resource_info:type_name -> soong_build_metrics.ProcessResourceInfo
+	10, // 18: soong_build_metrics.PerfCounters.groups:type_name -> soong_build_metrics.PerfCounterGroup
+	11, // 19: soong_build_metrics.PerfCounterGroup.counters:type_name -> soong_build_metrics.PerfCounter
+	3,  // 20: soong_build_metrics.ModuleTypeInfo.build_system:type_name -> soong_build_metrics.ModuleTypeInfo.BuildSystem
+	5,  // 21: soong_build_metrics.CriticalUserJourneyMetrics.metrics:type_name -> soong_build_metrics.MetricsBase
+	14, // 22: soong_build_metrics.CriticalUserJourneysMetrics.cujs:type_name -> soong_build_metrics.CriticalUserJourneyMetrics
+	8,  // 23: soong_build_metrics.SoongBuildMetrics.events:type_name -> soong_build_metrics.PerfInfo
+	18, // 24: soong_build_metrics.SoongBuildMetrics.mixed_builds_info:type_name -> soong_build_metrics.MixedBuildsInfo
+	9,  // 25: soong_build_metrics.SoongBuildMetrics.perf_counters:type_name -> soong_build_metrics.PerfCounters
+	4,  // 26: soong_build_metrics.ExpConfigFetcher.status:type_name -> soong_build_metrics.ExpConfigFetcher.ConfigStatus
+	20, // 27: soong_build_metrics.CriticalPathInfo.critical_path:type_name -> soong_build_metrics.JobInfo
+	20, // 28: soong_build_metrics.CriticalPathInfo.long_running_jobs:type_name -> soong_build_metrics.JobInfo
+	8,  // 29: soong_build_metrics.OptimizedBuildMetrics.analysis_perf:type_name -> soong_build_metrics.PerfInfo
+	8,  // 30: soong_build_metrics.OptimizedBuildMetrics.packaging_perf:type_name -> soong_build_metrics.PerfInfo
+	22, // 31: soong_build_metrics.OptimizedBuildMetrics.target_result:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult
+	8,  // 32: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.packaging_perf:type_name -> soong_build_metrics.PerfInfo
+	23, // 33: soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.output_artifact:type_name -> soong_build_metrics.OptimizedBuildMetrics.TargetOptimizationResult.OutputArtifact
+	34, // [34:34] is the sub-list for method output_type
+	34, // [34:34] is the sub-list for method input_type
+	34, // [34:34] is the sub-list for extension type_name
+	34, // [34:34] is the sub-list for extension extendee
+	0,  // [0:34] is the sub-list for field type_name
 }
 
 func init() { file_metrics_proto_init() }
@@ -2456,6 +2741,42 @@
 				return nil
 			}
 		}
+		file_metrics_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OptimizedBuildMetrics); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_metrics_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_metrics_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*OptimizedBuildMetrics_TargetOptimizationResult_OutputArtifact); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -2463,7 +2784,7 @@
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_metrics_proto_rawDesc,
 			NumEnums:      5,
-			NumMessages:   16,
+			NumMessages:   19,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 11fcba7..0989acf 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -137,6 +137,9 @@
   // Note that not all changed environment variables result in analysis retriggering.
   // If there was no previous build, this list will be empty.
   repeated string changed_environment_variable = 34;
+
+  // Metrics related to optimized builds.
+  optional OptimizedBuildMetrics optimized_build_metrics = 35;
 }
 
 message BuildConfig {
@@ -385,3 +388,35 @@
   // Description of a job
   optional string job_description = 2;
 }
+
+message OptimizedBuildMetrics {
+  // The total time spent analyzing what/how to optimize everything.
+  optional PerfInfo analysis_perf = 1;
+  // The total time spent packaging artifacts.
+  optional PerfInfo packaging_perf = 2;
+  // Information for a single target (e.g. general-tests).
+  repeated TargetOptimizationResult target_result = 3;
+
+  message TargetOptimizationResult {
+    // Target name (e.g. general-tests).
+    optional string name = 1;
+    // Whether or not this target was optimized.
+    optional bool optimized = 2;
+    // Reasoning for why the target wasn't optimized if it wasn't
+    optional string optimization_rationale = 3;
+    // Time spent packaging this specific target (if it was optimized).
+    optional PerfInfo packaging_perf = 4;
+    // Information for each different artifact produced by this target (if it
+    // was optimized).
+    repeated OutputArtifact output_artifact = 5;
+
+    message OutputArtifact {
+      // Artifact file name (e.g. general-tests.zip)
+      optional string name = 1;
+      // Size of the file.
+      optional int64 size = 2;
+      // Lists of modules packaged into this artifact.
+      repeated string included_modules = 3;
+    }
+  }
+}