Merge "Revert "error for non-system, non-vendor fuzzer"" into main
diff --git a/README.md b/README.md
index ad282a5..6d1a2c5 100644
--- a/README.md
+++ b/README.md
@@ -673,8 +673,7 @@
 SOONG_DELVE=2345 SOONG_DELVE_STEPS='build,modulegraph' m
 ```
 results in only `build` (main build step) and `modulegraph` being run in the debugger.
-The allowed step names are `bp2build_files`, `bp2build_workspace`, `build`,
-`modulegraph`, `queryview`, `soong_docs`.
+The allowed step names are `build`, `soong_docs`.
 
 Note setting or unsetting `SOONG_DELVE` causes a recompilation of `soong_build`. This
 is because in order to debug the binary, it needs to be built with debug
diff --git a/android/config.go b/android/config.go
index 5132c62..1e51840 100644
--- a/android/config.go
+++ b/android/config.go
@@ -84,7 +84,6 @@
 	SoongOutDir    string
 	SoongVariables string
 
-	BazelQueryViewDir string
 	ModuleGraphFile   string
 	ModuleActionsFile string
 	DocFile           string
@@ -99,11 +98,6 @@
 	// Don't use bazel at all during module analysis.
 	AnalysisNoBazel SoongBuildMode = iota
 
-	// Generate BUILD files which faithfully represent the dependency graph of
-	// blueprint modules. Individual BUILD targets will not, however, faitfhully
-	// express build semantics.
-	GenerateQueryView
-
 	// Create a JSON representation of the module graph and exit.
 	GenerateModuleGraph
 
@@ -716,7 +710,6 @@
 			config.BuildMode = mode
 		}
 	}
-	setBuildMode(cmdArgs.BazelQueryViewDir, GenerateQueryView)
 	setBuildMode(cmdArgs.ModuleGraphFile, GenerateModuleGraph)
 	setBuildMode(cmdArgs.DocFile, GenerateDocFile)
 
@@ -1524,6 +1517,10 @@
 	return "vendor"
 }
 
+func (c *deviceConfig) BuildingVendorImage() bool {
+	return proptools.Bool(c.config.productVariables.BuildingVendorImage)
+}
+
 func (c *deviceConfig) CurrentApiLevelForVendorModules() string {
 	return StringDefault(c.config.productVariables.DeviceCurrentApiLevelForVendorModules, "current")
 }
@@ -1554,6 +1551,10 @@
 	return "product"
 }
 
+func (c *deviceConfig) BuildingProductImage() bool {
+	return proptools.Bool(c.config.productVariables.BuildingProductImage)
+}
+
 func (c *deviceConfig) SystemExtPath() string {
 	if c.config.productVariables.SystemExtPath != nil {
 		return *c.config.productVariables.SystemExtPath
diff --git a/android/filegroup.go b/android/filegroup.go
index a8b4f00..67e5add1f 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -41,6 +41,14 @@
 
 	Exclude_srcs proptools.Configurable[[]string] `android:"path"`
 
+	// Sources the will be included in the filegroup, but any module dependencies will be added
+	// using the device os and the device's first architecture's variant.
+	Device_first_srcs proptools.Configurable[[]string] `android:"path_device_first"`
+
+	// Sources the will be included in the filegroup, but any module dependencies will be added
+	// using the device os and the common architecture's variant.
+	Device_common_srcs proptools.Configurable[[]string] `android:"path_device_common"`
+
 	// The base path to the files.  May be used by other modules to determine which portion
 	// of the path to use.  For example, when a filegroup is used as data in a cc_test rule,
 	// the base path is stripped off the path and the remaining path is used as the
@@ -90,11 +98,13 @@
 }
 
 func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
-	fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs.GetOrDefault(ctx, nil), fg.properties.Exclude_srcs.GetOrDefault(ctx, nil))
+	srcs := PathsForModuleSrcExcludes(ctx, fg.properties.Srcs.GetOrDefault(ctx, nil), fg.properties.Exclude_srcs.GetOrDefault(ctx, nil))
+	srcs = append(srcs, PathsForModuleSrc(ctx, fg.properties.Device_first_srcs.GetOrDefault(ctx, nil))...)
+	srcs = append(srcs, PathsForModuleSrc(ctx, fg.properties.Device_common_srcs.GetOrDefault(ctx, nil))...)
 	if fg.properties.Path != nil {
-		fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
+		srcs = PathsWithModuleSrcSubDir(ctx, srcs, String(fg.properties.Path))
 	}
-	SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: fg.srcs.Strings()})
+	SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
 
 	var aconfigDeclarations []string
 	var intermediateCacheOutputPaths Paths
@@ -108,6 +118,8 @@
 			maps.Copy(modeInfos, dep.ModeInfos)
 		}
 	})
+
+	fg.srcs = srcs
 	SetProvider(ctx, CodegenInfoProvider, CodegenInfo{
 		AconfigDeclarations:          aconfigDeclarations,
 		IntermediateCacheOutputPaths: intermediateCacheOutputPaths,
diff --git a/android/image.go b/android/image.go
index 6e5a551..012267a 100644
--- a/android/image.go
+++ b/android/image.go
@@ -14,44 +14,61 @@
 
 package android
 
+type ImageInterfaceContext interface {
+	ArchModuleContext
+
+	Module() Module
+
+	ModuleErrorf(fmt string, args ...interface{})
+	PropertyErrorf(property, fmt string, args ...interface{})
+
+	DeviceSpecific() bool
+	SocSpecific() bool
+	ProductSpecific() bool
+	SystemExtSpecific() bool
+	Platform() bool
+
+	Config() Config
+}
+
 // ImageInterface is implemented by modules that need to be split by the imageTransitionMutator.
 type ImageInterface interface {
 	// ImageMutatorBegin is called before any other method in the ImageInterface.
-	ImageMutatorBegin(ctx BaseModuleContext)
+	ImageMutatorBegin(ctx ImageInterfaceContext)
 
 	// VendorVariantNeeded should return true if the module needs a vendor variant (installed on the vendor image).
-	VendorVariantNeeded(ctx BaseModuleContext) bool
+	VendorVariantNeeded(ctx ImageInterfaceContext) bool
 
 	// ProductVariantNeeded should return true if the module needs a product variant (installed on the product image).
-	ProductVariantNeeded(ctx BaseModuleContext) bool
+	ProductVariantNeeded(ctx ImageInterfaceContext) bool
 
 	// CoreVariantNeeded should return true if the module needs a core variant (installed on the system image).
-	CoreVariantNeeded(ctx BaseModuleContext) bool
+	CoreVariantNeeded(ctx ImageInterfaceContext) bool
 
 	// RamdiskVariantNeeded should return true if the module needs a ramdisk variant (installed on the
 	// ramdisk partition).
-	RamdiskVariantNeeded(ctx BaseModuleContext) bool
+	RamdiskVariantNeeded(ctx ImageInterfaceContext) bool
 
 	// VendorRamdiskVariantNeeded should return true if the module needs a vendor ramdisk variant (installed on the
 	// vendor ramdisk partition).
-	VendorRamdiskVariantNeeded(ctx BaseModuleContext) bool
+	VendorRamdiskVariantNeeded(ctx ImageInterfaceContext) bool
 
 	// DebugRamdiskVariantNeeded should return true if the module needs a debug ramdisk variant (installed on the
 	// debug ramdisk partition: $(PRODUCT_OUT)/debug_ramdisk).
-	DebugRamdiskVariantNeeded(ctx BaseModuleContext) bool
+	DebugRamdiskVariantNeeded(ctx ImageInterfaceContext) bool
 
 	// RecoveryVariantNeeded should return true if the module needs a recovery variant (installed on the
 	// recovery partition).
-	RecoveryVariantNeeded(ctx BaseModuleContext) bool
+	RecoveryVariantNeeded(ctx ImageInterfaceContext) bool
 
 	// ExtraImageVariations should return a list of the additional variations needed for the module.  After the
 	// variants are created the SetImageVariation method will be called on each newly created variant with the
 	// its variation.
-	ExtraImageVariations(ctx BaseModuleContext) []string
+	ExtraImageVariations(ctx ImageInterfaceContext) []string
 
 	// SetImageVariation is called for each newly created image variant. The receiver is the original
 	// module, "variation" is the name of the newly created variant. "variation" is set on the receiver.
-	SetImageVariation(ctx BaseModuleContext, variation string)
+	SetImageVariation(ctx ImageInterfaceContext, variation string)
 }
 
 const (
diff --git a/android/packaging.go b/android/packaging.go
index d615871..fe76bfc 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -377,7 +377,17 @@
 			if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
 				continue
 			}
-			ctx.AddFarVariationDependencies(t.Variations(), depTag, dep)
+			targetVariation := t.Variations()
+			sharedVariation := blueprint.Variation{
+				Mutator:   "link",
+				Variation: "shared",
+			}
+			// If a shared variation exists, use that. Static variants do not provide any standalone files
+			// for packaging.
+			if ctx.OtherModuleFarDependencyVariantExists([]blueprint.Variation{sharedVariation}, dep) {
+				targetVariation = append(targetVariation, sharedVariation)
+			}
+			ctx.AddFarVariationDependencies(targetVariation, depTag, dep)
 		}
 	}
 }
@@ -385,6 +395,11 @@
 func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec {
 	// all packaging specs gathered from the dep.
 	var all []PackagingSpec
+	// Name of the dependency which requested the packaging spec.
+	// If this dep is overridden, the packaging spec will not be installed via this dependency chain.
+	// (the packaging spec might still be installed if there are some other deps which depend on it).
+	var depNames []string
+
 	// list of module names overridden
 	var overridden []string
 
@@ -419,6 +434,7 @@
 				}
 			}
 			all = append(all, ps)
+			depNames = append(depNames, child.Name())
 			if ps.overrides != nil {
 				overridden = append(overridden, *ps.overrides...)
 			}
@@ -427,10 +443,14 @@
 
 	// all minus packaging specs that are overridden
 	var filtered []PackagingSpec
-	for _, ps := range all {
+	for index, ps := range all {
 		if ps.owner != "" && InList(ps.owner, overridden) {
 			continue
 		}
+		// The dependency which requested this packaging spec has been overridden.
+		if InList(depNames[index], overridden) {
+			continue
+		}
 		filtered = append(filtered, ps)
 	}
 
diff --git a/android/packaging_test.go b/android/packaging_test.go
index f5b1020..9c6760c 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -64,7 +64,7 @@
 	ModuleBase
 	PackagingBase
 	properties struct {
-		Install_deps []string `android:`
+		Install_deps []string
 	}
 	entries []string
 }
diff --git a/android/path_properties.go b/android/path_properties.go
index d80a8ed..8ada133 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -18,6 +18,7 @@
 	"fmt"
 	"reflect"
 
+	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
 )
 
@@ -38,20 +39,32 @@
 		// squashed into the real modules.
 		return
 	}
+	if !ctx.Module().Enabled(ctx) {
+		return
+	}
 	props := ctx.Module().base().GetProperties()
 	addPathDepsForProps(ctx, props)
 }
 
 func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) {
 	// Iterate through each property struct of the module extracting the contents of all properties
-	// tagged with `android:"path"`.
+	// tagged with `android:"path"` or one of the variant-specifying tags.
 	var pathProperties []string
+	var pathDeviceFirstProperties []string
+	var pathDeviceCommonProperties []string
+	var pathCommonOsProperties []string
 	for _, ps := range props {
-		pathProperties = append(pathProperties, pathPropertiesForPropertyStruct(ctx, ps)...)
+		pathProperties = append(pathProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path")...)
+		pathDeviceFirstProperties = append(pathDeviceFirstProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first")...)
+		pathDeviceCommonProperties = append(pathDeviceCommonProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_common")...)
+		pathCommonOsProperties = append(pathCommonOsProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_common_os")...)
 	}
 
 	// Remove duplicates to avoid multiple dependencies.
 	pathProperties = FirstUniqueStrings(pathProperties)
+	pathDeviceFirstProperties = FirstUniqueStrings(pathDeviceFirstProperties)
+	pathDeviceCommonProperties = FirstUniqueStrings(pathDeviceCommonProperties)
+	pathCommonOsProperties = FirstUniqueStrings(pathCommonOsProperties)
 
 	// Add dependencies to anything that is a module reference.
 	for _, s := range pathProperties {
@@ -59,12 +72,35 @@
 			ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
 		}
 	}
+	// For properties tagged "path_device_first", use the first arch device variant when adding
+	// dependencies. This allows host modules to have some properties that add dependencies on
+	// device modules.
+	for _, s := range pathDeviceFirstProperties {
+		if m, t := SrcIsModuleWithTag(s); m != "" {
+			ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), sourceOrOutputDepTag(m, t), m)
+		}
+	}
+	// properties tagged "path_device_common" get the device common variant
+	for _, s := range pathDeviceCommonProperties {
+		if m, t := SrcIsModuleWithTag(s); m != "" {
+			ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), sourceOrOutputDepTag(m, t), m)
+		}
+	}
+	// properties tagged "path_device_common" get the device common variant
+	for _, s := range pathCommonOsProperties {
+		if m, t := SrcIsModuleWithTag(s); m != "" {
+			ctx.AddVariationDependencies([]blueprint.Variation{
+				{Mutator: "os", Variation: "common_os"},
+				{Mutator: "arch", Variation: ""},
+			}, sourceOrOutputDepTag(m, t), m)
+		}
+	}
 }
 
-// pathPropertiesForPropertyStruct uses the indexes of properties that are tagged with
-// android:"path" to extract all their values from a property struct, returning them as a single
+// taggedPropertiesForPropertyStruct uses the indexes of properties that are tagged with
+// android:"tagValue" to extract all their values from a property struct, returning them as a single
 // slice of strings.
-func pathPropertiesForPropertyStruct(ctx BottomUpMutatorContext, ps interface{}) []string {
+func taggedPropertiesForPropertyStruct(ctx BottomUpMutatorContext, ps interface{}, tagValue string) []string {
 	v := reflect.ValueOf(ps)
 	if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
 		panic(fmt.Errorf("type %s is not a pointer to a struct", v.Type()))
@@ -79,7 +115,7 @@
 	v = v.Elem()
 
 	// Get or create the list of indexes of properties that are tagged with `android:"path"`.
-	pathPropertyIndexes := pathPropertyIndexesForPropertyStruct(ps)
+	pathPropertyIndexes := taggedPropertyIndexesForPropertyStruct(ps, tagValue)
 
 	var ret []string
 
@@ -172,12 +208,20 @@
 
 var pathPropertyIndexesCache OncePer
 
-// pathPropertyIndexesForPropertyStruct returns a list of all of the indexes of properties in
-// property struct type that are tagged with `android:"path"`.  Each index is a []int suitable for
-// passing to reflect.Value.FieldByIndex.  The value is cached in a global cache by type.
-func pathPropertyIndexesForPropertyStruct(ps interface{}) [][]int {
-	key := NewCustomOnceKey(reflect.TypeOf(ps))
+// taggedPropertyIndexesForPropertyStruct returns a list of all of the indexes of properties in
+// property struct type that are tagged with `android:"tagValue"`.  Each index is a []int suitable
+// for passing to reflect.Value.FieldByIndex.  The value is cached in a global cache by type and
+// tagValue.
+func taggedPropertyIndexesForPropertyStruct(ps interface{}, tagValue string) [][]int {
+	type pathPropertyIndexesOnceKey struct {
+		propStructType reflect.Type
+		tagValue       string
+	}
+	key := NewCustomOnceKey(pathPropertyIndexesOnceKey{
+		propStructType: reflect.TypeOf(ps),
+		tagValue:       tagValue,
+	})
 	return pathPropertyIndexesCache.Once(key, func() interface{} {
-		return proptools.PropertyIndexesWithTag(ps, "android", "path")
+		return proptools.PropertyIndexesWithTag(ps, "android", tagValue)
 	}).([][]int)
 }
diff --git a/android/variable.go b/android/variable.go
index 73c0d0e..13d5f05 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -337,10 +337,12 @@
 	HWASanIncludePaths []string `json:",omitempty"`
 	HWASanExcludePaths []string `json:",omitempty"`
 
-	VendorPath    *string `json:",omitempty"`
-	OdmPath       *string `json:",omitempty"`
-	ProductPath   *string `json:",omitempty"`
-	SystemExtPath *string `json:",omitempty"`
+	VendorPath           *string `json:",omitempty"`
+	BuildingVendorImage  *bool   `json:",omitempty"`
+	OdmPath              *string `json:",omitempty"`
+	ProductPath          *string `json:",omitempty"`
+	BuildingProductImage *bool   `json:",omitempty"`
+	SystemExtPath        *string `json:",omitempty"`
 
 	ClangTidy  *bool   `json:",omitempty"`
 	TidyChecks *string `json:",omitempty"`
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 68978b2..bf4158c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -11342,7 +11342,7 @@
 		}
 		filegroup {
 			name: "qux-filegroup",
-			srcs: [
+			device_common_srcs: [
 				":qux-lib{.generated_srcjars}",
 			],
 		}
diff --git a/bin/soongdbg b/bin/soongdbg
index 98d31eb..0807291 100755
--- a/bin/soongdbg
+++ b/bin/soongdbg
@@ -393,12 +393,42 @@
                 print(f"    dep:      {d.id}")
 
 
+class StarCommand:
+    help = "Print the dependencies and reverse dependencies of a module"
+
+    def args(self, parser):
+        parser.add_argument("module", nargs="+",
+                            help="Module to print dependencies of")
+        parser.add_argument("--depth", type=int, required=True,
+                            help="max depth of dependencies")
+        print_args(parser)
+
+    def run(self, args):
+        graph = load_graph()
+        nodes = set()
+        err = False
+        for id in args.module:
+            root = graph.nodes.get(id)
+            if not root:
+                sys.stderr.write(f"error: Can't find root: {id}\n")
+                err = True
+                continue
+            get_deps(nodes, root, args.depth, False, set(args.tag))
+            nodes.remove(root) # Remove it so get_deps doesn't bail out
+            get_deps(nodes, root, args.depth, True, set(args.tag))
+        if err:
+            sys.exit(1)
+        print_nodes(args, nodes, new_module_formatter(args))
+
+
+
 COMMANDS = {
     "between": BetweenCommand(),
     "deps": DepsCommand(),
     "id": IdCommand(),
     "json": JsonCommand(),
     "query": QueryCommand(),
+    "star": StarCommand(),
 }
 
 
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
deleted file mode 100644
index 28c0268..0000000
--- a/bp2build/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-bootstrap_go_package {
-    name: "soong-bp2build",
-    pkgPath: "android/soong/bp2build",
-    srcs: [
-        "androidbp_to_build_templates.go",
-        "build_conversion.go",
-        "bzl_conversion.go",
-        "constants.go",
-        "conversion.go",
-    ],
-    deps: [
-        "blueprint-bootstrap",
-        "soong-aidl-library",
-        "soong-aconfig",
-        "soong-android",
-        "soong-android-allowlists",
-        "soong-android-soongconfig",
-        "soong-apex",
-        "soong-cc",
-        "soong-cc-config",
-        "soong-etc",
-        "soong-genrule",
-        "soong-linkerconfig",
-        "soong-python",
-        "soong-rust",
-        "soong-sh",
-        "soong-shared",
-        "soong-starlark-format",
-        "soong-ui-metrics",
-    ],
-    testSrcs: [
-        "conversion_test.go",
-    ],
-    pluginFor: [
-        "soong_build",
-    ],
-}
diff --git a/bp2build/androidbp_to_build_templates.go b/bp2build/androidbp_to_build_templates.go
deleted file mode 100644
index 9b21c32..0000000
--- a/bp2build/androidbp_to_build_templates.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-const (
-	// The default `load` preamble for every generated queryview BUILD file.
-	soongModuleLoad = `package(default_visibility = ["//visibility:public"])
-load("//build/bazel/queryview_rules:soong_module.bzl", "soong_module")
-
-`
-
-	// A macro call in the BUILD file representing a Soong module, with space
-	// for expanding more attributes.
-	soongModuleTargetTemplate = `soong_module(
-    name = "%s",
-    soong_module_name = "%s",
-    soong_module_type = "%s",
-    soong_module_variant = "%s",
-    soong_module_deps = %s,
-%s)`
-
-	ruleTargetTemplate = `%s(
-    name = "%s",
-%s)`
-
-	unnamedRuleTargetTemplate = `%s(
-%s)`
-
-	// A simple provider to mark and differentiate Soong module rule shims from
-	// regular Bazel rules. Every Soong module rule shim returns a
-	// SoongModuleInfo provider, and can only depend on rules returning
-	// SoongModuleInfo in the `soong_module_deps` attribute.
-	providersBzl = `SoongModuleInfo = provider(
-    fields = {
-        "name": "Name of module",
-        "type": "Type of module",
-        "variant": "Variant of module",
-    },
-)
-`
-
-	// The soong_module rule implementation in a .bzl file.
-	soongModuleBzl = `
-%s
-
-load("//build/bazel/queryview_rules:providers.bzl", "SoongModuleInfo")
-
-def _generic_soong_module_impl(ctx):
-    return [
-        SoongModuleInfo(
-            name = ctx.attr.soong_module_name,
-            type = ctx.attr.soong_module_type,
-            variant = ctx.attr.soong_module_variant,
-        ),
-    ]
-
-generic_soong_module = rule(
-    implementation = _generic_soong_module_impl,
-    attrs = {
-        "soong_module_name": attr.string(mandatory = True),
-        "soong_module_type": attr.string(mandatory = True),
-        "soong_module_variant": attr.string(),
-        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
-    },
-)
-
-soong_module_rule_map = {
-%s}
-
-_SUPPORTED_TYPES = ["bool", "int", "string"]
-
-def _is_supported_type(value):
-    if type(value) in _SUPPORTED_TYPES:
-        return True
-    elif type(value) == "list":
-        supported = True
-        for v in value:
-            supported = supported and type(v) in _SUPPORTED_TYPES
-        return supported
-    else:
-        return False
-
-# soong_module is a macro that supports arbitrary kwargs, and uses soong_module_type to
-# expand to the right underlying shim.
-def soong_module(name, soong_module_type, **kwargs):
-    soong_module_rule = soong_module_rule_map.get(soong_module_type)
-
-    if soong_module_rule == None:
-        # This module type does not have an existing rule to map to, so use the
-        # generic_soong_module rule instead.
-        generic_soong_module(
-            name = name,
-            soong_module_type = soong_module_type,
-            soong_module_name = kwargs.pop("soong_module_name", ""),
-            soong_module_variant = kwargs.pop("soong_module_variant", ""),
-            soong_module_deps = kwargs.pop("soong_module_deps", []),
-        )
-    else:
-        supported_kwargs = dict()
-        for key, value in kwargs.items():
-            if _is_supported_type(value):
-                supported_kwargs[key] = value
-        soong_module_rule(
-            name = name,
-            **supported_kwargs,
-        )
-`
-
-	// A rule shim for representing a Soong module type and its properties.
-	moduleRuleShim = `
-def _%[1]s_impl(ctx):
-    return [SoongModuleInfo()]
-
-%[1]s = rule(
-    implementation = _%[1]s_impl,
-    attrs = %[2]s
-)
-`
-)
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
deleted file mode 100644
index 18213a8..0000000
--- a/bp2build/build_conversion.go
+++ /dev/null
@@ -1,618 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-/*
-For shareable/common functionality for conversion from soong-module to build files
-for queryview/bp2build
-*/
-
-import (
-	"fmt"
-	"reflect"
-	"sort"
-	"strings"
-
-	"android/soong/android"
-	"android/soong/starlark_fmt"
-	"github.com/google/blueprint"
-	"github.com/google/blueprint/proptools"
-)
-
-type BazelAttributes struct {
-	Attrs map[string]string
-}
-
-type BazelLoadSymbol struct {
-	// The name of the symbol in the file being loaded
-	symbol string
-	// The name the symbol wil have in this file. Can be left blank to use the same name as symbol.
-	alias string
-}
-
-type BazelLoad struct {
-	file    string
-	symbols []BazelLoadSymbol
-}
-
-type BazelTarget struct {
-	name        string
-	packageName string
-	content     string
-	ruleClass   string
-	loads       []BazelLoad
-}
-
-// Label is the fully qualified Bazel label constructed from the BazelTarget's
-// package name and target name.
-func (t BazelTarget) Label() string {
-	if t.packageName == "." {
-		return "//:" + t.name
-	} else {
-		return "//" + t.packageName + ":" + t.name
-	}
-}
-
-// PackageName returns the package of the Bazel target.
-// Defaults to root of tree.
-func (t BazelTarget) PackageName() string {
-	if t.packageName == "" {
-		return "."
-	}
-	return t.packageName
-}
-
-// BazelTargets is a typedef for a slice of BazelTarget objects.
-type BazelTargets []BazelTarget
-
-func (targets BazelTargets) packageRule() *BazelTarget {
-	for _, target := range targets {
-		if target.ruleClass == "package" {
-			return &target
-		}
-	}
-	return nil
-}
-
-// sort a list of BazelTargets in-place, by name, and by generated/handcrafted types.
-func (targets BazelTargets) sort() {
-	sort.Slice(targets, func(i, j int) bool {
-		return targets[i].name < targets[j].name
-	})
-}
-
-// String returns the string representation of BazelTargets, without load
-// statements (use LoadStatements for that), since the targets are usually not
-// adjacent to the load statements at the top of the BUILD file.
-func (targets BazelTargets) String() string {
-	var res strings.Builder
-	for i, target := range targets {
-		if target.ruleClass != "package" {
-			res.WriteString(target.content)
-		}
-		if i != len(targets)-1 {
-			res.WriteString("\n\n")
-		}
-	}
-	return res.String()
-}
-
-// LoadStatements return the string representation of the sorted and deduplicated
-// Starlark rule load statements needed by a group of BazelTargets.
-func (targets BazelTargets) LoadStatements() string {
-	// First, merge all the load statements from all the targets onto one list
-	bzlToLoadedSymbols := map[string][]BazelLoadSymbol{}
-	for _, target := range targets {
-		for _, load := range target.loads {
-		outer:
-			for _, symbol := range load.symbols {
-				alias := symbol.alias
-				if alias == "" {
-					alias = symbol.symbol
-				}
-				for _, otherSymbol := range bzlToLoadedSymbols[load.file] {
-					otherAlias := otherSymbol.alias
-					if otherAlias == "" {
-						otherAlias = otherSymbol.symbol
-					}
-					if symbol.symbol == otherSymbol.symbol && alias == otherAlias {
-						continue outer
-					} else if alias == otherAlias {
-						panic(fmt.Sprintf("Conflicting destination (%s) for loads of %s and %s", alias, symbol.symbol, otherSymbol.symbol))
-					}
-				}
-				bzlToLoadedSymbols[load.file] = append(bzlToLoadedSymbols[load.file], symbol)
-			}
-		}
-	}
-
-	var loadStatements strings.Builder
-	for i, bzl := range android.SortedKeys(bzlToLoadedSymbols) {
-		symbols := bzlToLoadedSymbols[bzl]
-		loadStatements.WriteString("load(\"")
-		loadStatements.WriteString(bzl)
-		loadStatements.WriteString("\", ")
-		sort.Slice(symbols, func(i, j int) bool {
-			if symbols[i].symbol < symbols[j].symbol {
-				return true
-			}
-			return symbols[i].alias < symbols[j].alias
-		})
-		for j, symbol := range symbols {
-			if symbol.alias != "" && symbol.alias != symbol.symbol {
-				loadStatements.WriteString(symbol.alias)
-				loadStatements.WriteString(" = ")
-			}
-			loadStatements.WriteString("\"")
-			loadStatements.WriteString(symbol.symbol)
-			loadStatements.WriteString("\"")
-			if j != len(symbols)-1 {
-				loadStatements.WriteString(", ")
-			}
-		}
-		loadStatements.WriteString(")")
-		if i != len(bzlToLoadedSymbols)-1 {
-			loadStatements.WriteString("\n")
-		}
-	}
-	return loadStatements.String()
-}
-
-type bpToBuildContext interface {
-	ModuleName(module blueprint.Module) string
-	ModuleDir(module blueprint.Module) string
-	ModuleSubDir(module blueprint.Module) string
-	ModuleType(module blueprint.Module) string
-
-	VisitAllModules(visit func(blueprint.Module))
-	VisitDirectDeps(module blueprint.Module, visit func(blueprint.Module))
-}
-
-type CodegenContext struct {
-	config         android.Config
-	context        *android.Context
-	mode           CodegenMode
-	additionalDeps []string
-	topDir         string
-}
-
-func (ctx *CodegenContext) Mode() CodegenMode {
-	return ctx.mode
-}
-
-// CodegenMode is an enum to differentiate code-generation modes.
-type CodegenMode int
-
-const (
-	// QueryView - generate BUILD files with targets representing fully mutated
-	// Soong modules, representing the fully configured Soong module graph with
-	// variants and dependency edges.
-	//
-	// This mode is used for discovering and introspecting the existing Soong
-	// module graph.
-	QueryView CodegenMode = iota
-)
-
-func (mode CodegenMode) String() string {
-	switch mode {
-	case QueryView:
-		return "QueryView"
-	default:
-		return fmt.Sprintf("%d", mode)
-	}
-}
-
-// AddNinjaFileDeps adds dependencies on the specified files to be added to the ninja manifest. The
-// primary builder will be rerun whenever the specified files are modified. Allows us to fulfill the
-// PathContext interface in order to add dependencies on hand-crafted BUILD files. Note: must also
-// call AdditionalNinjaDeps and add them manually to the ninja file.
-func (ctx *CodegenContext) AddNinjaFileDeps(deps ...string) {
-	ctx.additionalDeps = append(ctx.additionalDeps, deps...)
-}
-
-// AdditionalNinjaDeps returns additional ninja deps added by CodegenContext
-func (ctx *CodegenContext) AdditionalNinjaDeps() []string {
-	return ctx.additionalDeps
-}
-
-func (ctx *CodegenContext) Config() android.Config    { return ctx.config }
-func (ctx *CodegenContext) Context() *android.Context { return ctx.context }
-
-// NewCodegenContext creates a wrapper context that conforms to PathContext for
-// writing BUILD files in the output directory.
-func NewCodegenContext(config android.Config, context *android.Context, mode CodegenMode, topDir string) *CodegenContext {
-	return &CodegenContext{
-		context: context,
-		config:  config,
-		mode:    mode,
-		topDir:  topDir,
-	}
-}
-
-// props is an unsorted map. This function ensures that
-// the generated attributes are sorted to ensure determinism.
-func propsToAttributes(props map[string]string) string {
-	var attributes string
-	for _, propName := range android.SortedKeys(props) {
-		attributes += fmt.Sprintf("    %s = %s,\n", propName, props[propName])
-	}
-	return attributes
-}
-
-type conversionResults struct {
-	buildFileToTargets    map[string]BazelTargets
-	moduleNameToPartition map[string]string
-}
-
-func (r conversionResults) BuildDirToTargets() map[string]BazelTargets {
-	return r.buildFileToTargets
-}
-
-func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (conversionResults, []error) {
-	ctx.Context().BeginEvent("GenerateBazelTargets")
-	defer ctx.Context().EndEvent("GenerateBazelTargets")
-	buildFileToTargets := make(map[string]BazelTargets)
-
-	dirs := make(map[string]bool)
-	moduleNameToPartition := make(map[string]string)
-
-	var errs []error
-
-	bpCtx := ctx.Context()
-	bpCtx.VisitAllModules(func(m blueprint.Module) {
-		dir := bpCtx.ModuleDir(m)
-		dirs[dir] = true
-
-		var targets []BazelTarget
-
-		switch ctx.Mode() {
-		case QueryView:
-			// Blocklist certain module types from being generated.
-			if canonicalizeModuleType(bpCtx.ModuleType(m)) == "package" {
-				// package module name contain slashes, and thus cannot
-				// be mapped cleanly to a bazel label.
-				return
-			}
-			t, err := generateSoongModuleTarget(bpCtx, m)
-			if err != nil {
-				errs = append(errs, err)
-			}
-			targets = append(targets, t)
-		default:
-			errs = append(errs, fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
-			return
-		}
-
-		for _, target := range targets {
-			targetDir := target.PackageName()
-			buildFileToTargets[targetDir] = append(buildFileToTargets[targetDir], target)
-		}
-	})
-
-	if len(errs) > 0 {
-		return conversionResults{}, errs
-	}
-
-	if generateFilegroups {
-		// Add a filegroup target that exposes all sources in the subtree of this package
-		// NOTE: This also means we generate a BUILD file for every Android.bp file (as long as it has at least one module)
-		//
-		// This works because: https://bazel.build/reference/be/functions#exports_files
-		// "As a legacy behaviour, also files mentioned as input to a rule are exported with the
-		// default visibility until the flag --incompatible_no_implicit_file_export is flipped. However, this behavior
-		// should not be relied upon and actively migrated away from."
-		//
-		// TODO(b/198619163): We should change this to export_files(glob(["**/*"])) instead, but doing that causes these errors:
-		// "Error in exports_files: generated label '//external/avb:avbtool' conflicts with existing py_binary rule"
-		// So we need to solve all the "target ... is both a rule and a file" warnings first.
-		for dir := range dirs {
-			buildFileToTargets[dir] = append(buildFileToTargets[dir], BazelTarget{
-				name:      "bp2build_all_srcs",
-				content:   `filegroup(name = "bp2build_all_srcs", srcs = glob(["**/*"]), tags = ["manual"])`,
-				ruleClass: "filegroup",
-			})
-		}
-	}
-
-	return conversionResults{
-		buildFileToTargets:    buildFileToTargets,
-		moduleNameToPartition: moduleNameToPartition,
-	}, errs
-}
-
-// Convert a module and its deps and props into a Bazel macro/rule
-// representation in the BUILD file.
-func generateSoongModuleTarget(ctx bpToBuildContext, m blueprint.Module) (BazelTarget, error) {
-	props, err := getBuildProperties(ctx, m)
-
-	// TODO(b/163018919): DirectDeps can have duplicate (module, variant)
-	// items, if the modules are added using different DependencyTag. Figure
-	// out the implications of that.
-	depLabels := map[string]bool{}
-	if aModule, ok := m.(android.Module); ok {
-		ctx.VisitDirectDeps(aModule, func(depModule blueprint.Module) {
-			depLabels[qualifiedTargetLabel(ctx, depModule)] = true
-		})
-	}
-
-	for p := range ignoredPropNames {
-		delete(props.Attrs, p)
-	}
-	attributes := propsToAttributes(props.Attrs)
-
-	depLabelList := "[\n"
-	for depLabel := range depLabels {
-		depLabelList += fmt.Sprintf("        %q,\n", depLabel)
-	}
-	depLabelList += "    ]"
-
-	targetName := targetNameWithVariant(ctx, m)
-	return BazelTarget{
-		name:        targetName,
-		packageName: ctx.ModuleDir(m),
-		content: fmt.Sprintf(
-			soongModuleTargetTemplate,
-			targetName,
-			ctx.ModuleName(m),
-			canonicalizeModuleType(ctx.ModuleType(m)),
-			ctx.ModuleSubDir(m),
-			depLabelList,
-			attributes),
-	}, err
-}
-
-func getBuildProperties(ctx bpToBuildContext, m blueprint.Module) (BazelAttributes, error) {
-	// TODO: this omits properties for blueprint modules (blueprint_go_binary,
-	// bootstrap_go_binary, bootstrap_go_package), which will have to be handled separately.
-	if aModule, ok := m.(android.Module); ok {
-		return extractModuleProperties(aModule.GetProperties(), false)
-	}
-
-	return BazelAttributes{}, nil
-}
-
-// Generically extract module properties and types into a map, keyed by the module property name.
-func extractModuleProperties(props []interface{}, checkForDuplicateProperties bool) (BazelAttributes, error) {
-	ret := map[string]string{}
-
-	// Iterate over this android.Module's property structs.
-	for _, properties := range props {
-		propertiesValue := reflect.ValueOf(properties)
-		// Check that propertiesValue is a pointer to the Properties struct, like
-		// *cc.BaseLinkerProperties or *java.CompilerProperties.
-		//
-		// propertiesValue can also be type-asserted to the structs to
-		// manipulate internal props, if needed.
-		if isStructPtr(propertiesValue.Type()) {
-			structValue := propertiesValue.Elem()
-			ok, err := extractStructProperties(structValue, 0)
-			if err != nil {
-				return BazelAttributes{}, err
-			}
-			for k, v := range ok {
-				if existing, exists := ret[k]; checkForDuplicateProperties && exists {
-					return BazelAttributes{}, fmt.Errorf(
-						"%s (%v) is present in properties whereas it should be consolidated into a commonAttributes",
-						k, existing)
-				}
-				ret[k] = v
-			}
-		} else {
-			return BazelAttributes{},
-				fmt.Errorf(
-					"properties must be a pointer to a struct, got %T",
-					propertiesValue.Interface())
-		}
-	}
-
-	return BazelAttributes{
-		Attrs: ret,
-	}, nil
-}
-
-func isStructPtr(t reflect.Type) bool {
-	return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
-}
-
-// prettyPrint a property value into the equivalent Starlark representation
-// recursively.
-func prettyPrint(propertyValue reflect.Value, indent int, emitZeroValues bool) (string, error) {
-	if !emitZeroValues && isZero(propertyValue) {
-		// A property value being set or unset actually matters -- Soong does set default
-		// values for unset properties, like system_shared_libs = ["libc", "libm", "libdl"] at
-		// https://cs.android.com/android/platform/superproject/+/main:build/soong/cc/linker.go;l=281-287;drc=f70926eef0b9b57faf04c17a1062ce50d209e480
-		//
-		// In Bazel-parlance, we would use "attr.<type>(default = <default
-		// value>)" to set the default value of unset attributes. In the cases
-		// where the bp2build converter didn't set the default value within the
-		// mutator when creating the BazelTargetModule, this would be a zero
-		// value. For those cases, we return an empty string so we don't
-		// unnecessarily generate empty values.
-		return "", nil
-	}
-
-	switch propertyValue.Kind() {
-	case reflect.String:
-		return fmt.Sprintf("\"%v\"", escapeString(propertyValue.String())), nil
-	case reflect.Bool:
-		return starlark_fmt.PrintBool(propertyValue.Bool()), nil
-	case reflect.Int, reflect.Uint, reflect.Int64:
-		return fmt.Sprintf("%v", propertyValue.Interface()), nil
-	case reflect.Ptr:
-		return prettyPrint(propertyValue.Elem(), indent, emitZeroValues)
-	case reflect.Slice:
-		elements := make([]string, 0, propertyValue.Len())
-		for i := 0; i < propertyValue.Len(); i++ {
-			val, err := prettyPrint(propertyValue.Index(i), indent, emitZeroValues)
-			if err != nil {
-				return "", err
-			}
-			if val != "" {
-				elements = append(elements, val)
-			}
-		}
-		return starlark_fmt.PrintList(elements, indent, func(s string) string {
-			return "%s"
-		}), nil
-
-	case reflect.Struct:
-		// Sort and print the struct props by the key.
-		structProps, err := extractStructProperties(propertyValue, indent)
-
-		if err != nil {
-			return "", err
-		}
-
-		if len(structProps) == 0 {
-			return "", nil
-		}
-		return starlark_fmt.PrintDict(structProps, indent), nil
-	case reflect.Interface:
-		// TODO(b/164227191): implement pretty print for interfaces.
-		// Interfaces are used for for arch, multilib and target properties.
-		return "", nil
-	case reflect.Map:
-		if v, ok := propertyValue.Interface().(map[string]string); ok {
-			return starlark_fmt.PrintStringStringDict(v, indent), nil
-		}
-		return "", fmt.Errorf("bp2build expects map of type map[string]string for field: %s", propertyValue)
-	default:
-		return "", fmt.Errorf(
-			"unexpected kind for property struct field: %s", propertyValue.Kind())
-	}
-}
-
-// Converts a reflected property struct value into a map of property names and property values,
-// which each property value correctly pretty-printed and indented at the right nest level,
-// since property structs can be nested. In Starlark, nested structs are represented as nested
-// dicts: https://docs.bazel.build/skylark/lib/dict.html
-func extractStructProperties(structValue reflect.Value, indent int) (map[string]string, error) {
-	if structValue.Kind() != reflect.Struct {
-		return map[string]string{}, fmt.Errorf("Expected a reflect.Struct type, but got %s", structValue.Kind())
-	}
-
-	var err error
-
-	ret := map[string]string{}
-	structType := structValue.Type()
-	for i := 0; i < structValue.NumField(); i++ {
-		field := structType.Field(i)
-		if shouldSkipStructField(field) {
-			continue
-		}
-
-		fieldValue := structValue.Field(i)
-		if isZero(fieldValue) {
-			// Ignore zero-valued fields
-			continue
-		}
-
-		// if the struct is embedded (anonymous), flatten the properties into the containing struct
-		if field.Anonymous {
-			if field.Type.Kind() == reflect.Ptr {
-				fieldValue = fieldValue.Elem()
-			}
-			if fieldValue.Type().Kind() == reflect.Struct {
-				propsToMerge, err := extractStructProperties(fieldValue, indent)
-				if err != nil {
-					return map[string]string{}, err
-				}
-				for prop, value := range propsToMerge {
-					ret[prop] = value
-				}
-				continue
-			}
-		}
-
-		propertyName := proptools.PropertyNameForField(field.Name)
-		var prettyPrintedValue string
-		prettyPrintedValue, err = prettyPrint(fieldValue, indent+1, false)
-		if err != nil {
-			return map[string]string{}, fmt.Errorf(
-				"Error while parsing property: %q. %s",
-				propertyName,
-				err)
-		}
-		if prettyPrintedValue != "" {
-			ret[propertyName] = prettyPrintedValue
-		}
-	}
-
-	return ret, nil
-}
-
-func isZero(value reflect.Value) bool {
-	switch value.Kind() {
-	case reflect.Func, reflect.Map, reflect.Slice:
-		return value.IsNil()
-	case reflect.Array:
-		valueIsZero := true
-		for i := 0; i < value.Len(); i++ {
-			valueIsZero = valueIsZero && isZero(value.Index(i))
-		}
-		return valueIsZero
-	case reflect.Struct:
-		valueIsZero := true
-		for i := 0; i < value.NumField(); i++ {
-			valueIsZero = valueIsZero && isZero(value.Field(i))
-		}
-		return valueIsZero
-	case reflect.Ptr:
-		if !value.IsNil() {
-			return isZero(reflect.Indirect(value))
-		} else {
-			return true
-		}
-	// Always print bool/strings, if you want a bool/string attribute to be able to take the default value, use a
-	// pointer instead
-	case reflect.Bool, reflect.String:
-		return false
-	default:
-		if !value.IsValid() {
-			return true
-		}
-		zeroValue := reflect.Zero(value.Type())
-		result := value.Interface() == zeroValue.Interface()
-		return result
-	}
-}
-
-func escapeString(s string) string {
-	s = strings.ReplaceAll(s, "\\", "\\\\")
-
-	// b/184026959: Reverse the application of some common control sequences.
-	// These must be generated literally in the BUILD file.
-	s = strings.ReplaceAll(s, "\t", "\\t")
-	s = strings.ReplaceAll(s, "\n", "\\n")
-	s = strings.ReplaceAll(s, "\r", "\\r")
-
-	return strings.ReplaceAll(s, "\"", "\\\"")
-}
-
-func targetNameWithVariant(c bpToBuildContext, logicModule blueprint.Module) string {
-	name := ""
-	if c.ModuleSubDir(logicModule) != "" {
-		// TODO(b/162720883): Figure out a way to drop the "--" variant suffixes.
-		name = c.ModuleName(logicModule) + "--" + c.ModuleSubDir(logicModule)
-	} else {
-		name = c.ModuleName(logicModule)
-	}
-
-	return strings.Replace(name, "//", "", 1)
-}
-
-func qualifiedTargetLabel(c bpToBuildContext, logicModule blueprint.Module) string {
-	return fmt.Sprintf("//%s:%s", c.ModuleDir(logicModule), targetNameWithVariant(c, logicModule))
-}
diff --git a/bp2build/bzl_conversion.go b/bp2build/bzl_conversion.go
deleted file mode 100644
index e774fdf..0000000
--- a/bp2build/bzl_conversion.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-import (
-	"android/soong/android"
-	"fmt"
-	"reflect"
-	"runtime"
-	"sort"
-	"strings"
-
-	"github.com/google/blueprint/proptools"
-)
-
-var (
-	// An allowlist of prop types that are surfaced from module props to rule
-	// attributes. (nested) dictionaries are notably absent here, because while
-	// Soong supports multi value typed and nested dictionaries, Bazel's rule
-	// attr() API supports only single-level string_dicts.
-	allowedPropTypes = map[string]bool{
-		"int":         true, // e.g. 42
-		"bool":        true, // e.g. True
-		"string_list": true, // e.g. ["a", "b"]
-		"string":      true, // e.g. "a"
-	}
-)
-
-type rule struct {
-	name  string
-	attrs string
-}
-
-type RuleShim struct {
-	// The rule class shims contained in a bzl file. e.g. ["cc_object", "cc_library", ..]
-	rules []string
-
-	// The generated string content of the bzl file.
-	content string
-}
-
-// Create <module>.bzl containing Bazel rule shims for every module type available in Soong and
-// user-specified Go plugins.
-//
-// This function reuses documentation generation APIs to ensure parity between modules-as-docs
-// and modules-as-code, including the names and types of morule properties.
-func CreateRuleShims(moduleTypeFactories map[string]android.ModuleFactory) map[string]RuleShim {
-	ruleShims := map[string]RuleShim{}
-	for pkg, rules := range generateRules(moduleTypeFactories) {
-		shim := RuleShim{
-			rules: make([]string, 0, len(rules)),
-		}
-		shim.content = "load(\"//build/bazel/queryview_rules:providers.bzl\", \"SoongModuleInfo\")\n"
-
-		bzlFileName := strings.ReplaceAll(pkg, "android/soong/", "")
-		bzlFileName = strings.ReplaceAll(bzlFileName, ".", "_")
-		bzlFileName = strings.ReplaceAll(bzlFileName, "/", "_")
-
-		for _, r := range rules {
-			shim.content += fmt.Sprintf(moduleRuleShim, r.name, r.attrs)
-			shim.rules = append(shim.rules, r.name)
-		}
-		sort.Strings(shim.rules)
-		ruleShims[bzlFileName] = shim
-	}
-	return ruleShims
-}
-
-// Generate the content of soong_module.bzl with the rule shim load statements
-// and mapping of module_type to rule shim map for every module type in Soong.
-func generateSoongModuleBzl(bzlLoads map[string]RuleShim) string {
-	var loadStmts string
-	var moduleRuleMap string
-	for _, bzlFileName := range android.SortedKeys(bzlLoads) {
-		loadStmt := "load(\"//build/bazel/queryview_rules:"
-		loadStmt += bzlFileName
-		loadStmt += ".bzl\""
-		ruleShim := bzlLoads[bzlFileName]
-		for _, rule := range ruleShim.rules {
-			loadStmt += fmt.Sprintf(", %q", rule)
-			moduleRuleMap += "    \"" + rule + "\": " + rule + ",\n"
-		}
-		loadStmt += ")\n"
-		loadStmts += loadStmt
-	}
-
-	return fmt.Sprintf(soongModuleBzl, loadStmts, moduleRuleMap)
-}
-
-func generateRules(moduleTypeFactories map[string]android.ModuleFactory) map[string][]rule {
-	// TODO: add shims for bootstrap/blueprint go modules types
-
-	rules := make(map[string][]rule)
-	// TODO: allow registration of a bzl rule when registring a factory
-	for _, moduleType := range android.SortedKeys(moduleTypeFactories) {
-		factory := moduleTypeFactories[moduleType]
-		factoryName := runtime.FuncForPC(reflect.ValueOf(factory).Pointer()).Name()
-		pkg := strings.Split(factoryName, ".")[0]
-		attrs := `{
-        "soong_module_name": attr.string(mandatory = True),
-        "soong_module_variant": attr.string(),
-        "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
-`
-		attrs += getAttributes(factory)
-		attrs += "    },"
-
-		r := rule{
-			name:  canonicalizeModuleType(moduleType),
-			attrs: attrs,
-		}
-
-		rules[pkg] = append(rules[pkg], r)
-	}
-	return rules
-}
-
-type property struct {
-	name             string
-	starlarkAttrType string
-	properties       []property
-}
-
-const (
-	attributeIndent = "        "
-)
-
-func (p *property) attributeString() string {
-	if !shouldGenerateAttribute(p.name) {
-		return ""
-	}
-
-	if _, ok := allowedPropTypes[p.starlarkAttrType]; !ok {
-		// a struct -- let's just comment out sub-props
-		s := fmt.Sprintf(attributeIndent+"# %s start\n", p.name)
-		for _, nestedP := range p.properties {
-			s += "# " + nestedP.attributeString()
-		}
-		s += fmt.Sprintf(attributeIndent+"# %s end\n", p.name)
-		return s
-	}
-	return fmt.Sprintf(attributeIndent+"%q: attr.%s(),\n", p.name, p.starlarkAttrType)
-}
-
-func extractPropertyDescriptionsFromStruct(structType reflect.Type) []property {
-	properties := make([]property, 0)
-	for i := 0; i < structType.NumField(); i++ {
-		field := structType.Field(i)
-		if shouldSkipStructField(field) {
-			continue
-		}
-		subProps := extractPropertyDescriptions(field.Name, field.Type)
-		// if the struct is embedded (anonymous), flatten the properties into the containing struct
-		if field.Anonymous {
-			for _, prop := range subProps {
-				properties = append(properties, prop.properties...)
-			}
-		} else {
-			properties = append(properties, subProps...)
-		}
-	}
-	return properties
-}
-
-func extractPropertyDescriptions(name string, t reflect.Type) []property {
-	name = proptools.PropertyNameForField(name)
-
-	// TODO: handle android:paths tags, they should be changed to label types
-
-	starlarkAttrType := fmt.Sprintf("%s", t.Name())
-	props := make([]property, 0)
-
-	switch t.Kind() {
-	case reflect.Bool, reflect.String:
-		// do nothing
-	case reflect.Uint, reflect.Int, reflect.Int64:
-		starlarkAttrType = "int"
-	case reflect.Slice:
-		if t.Elem().Kind() != reflect.String {
-			// TODO: handle lists of non-strings (currently only list of Dist)
-			return []property{}
-		}
-		starlarkAttrType = "string_list"
-	case reflect.Struct:
-		props = extractPropertyDescriptionsFromStruct(t)
-	case reflect.Ptr:
-		return extractPropertyDescriptions(name, t.Elem())
-	case reflect.Interface:
-		// Interfaces are used for for arch, multilib and target properties, which are handled at runtime.
-		// These will need to be handled in a bazel-specific version of the arch mutator.
-		return []property{}
-	}
-
-	prop := property{
-		name:             name,
-		starlarkAttrType: starlarkAttrType,
-		properties:       props,
-	}
-
-	return []property{prop}
-}
-
-func getPropertyDescriptions(props []interface{}) []property {
-	// there may be duplicate properties, e.g. from defaults libraries
-	propertiesByName := make(map[string]property)
-	for _, p := range props {
-		for _, prop := range extractPropertyDescriptionsFromStruct(reflect.ValueOf(p).Elem().Type()) {
-			propertiesByName[prop.name] = prop
-		}
-	}
-
-	properties := make([]property, 0, len(propertiesByName))
-	for _, key := range android.SortedKeys(propertiesByName) {
-		properties = append(properties, propertiesByName[key])
-	}
-
-	return properties
-}
-
-func getAttributes(factory android.ModuleFactory) string {
-	attrs := ""
-	for _, p := range getPropertyDescriptions(factory().GetProperties()) {
-		attrs += p.attributeString()
-	}
-	return attrs
-}
diff --git a/bp2build/constants.go b/bp2build/constants.go
deleted file mode 100644
index 76ba106..0000000
--- a/bp2build/constants.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-var (
-	// When both a BUILD and BUILD.bazel file are exist in the same package, the BUILD.bazel file will
-	// be preferred for use within a Bazel build.
-
-	// The file name used for automatically generated files.
-	GeneratedBuildFileName = "BUILD.bazel"
-)
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
deleted file mode 100644
index 9f1aa09..0000000
--- a/bp2build/conversion.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package bp2build
-
-import (
-	"reflect"
-	"strings"
-
-	"android/soong/android"
-	"github.com/google/blueprint/proptools"
-)
-
-type BazelFile struct {
-	Dir      string
-	Basename string
-	Contents string
-}
-
-func CreateBazelFiles(ruleShims map[string]RuleShim, buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
-	var files []BazelFile
-
-	if mode == QueryView {
-		// Write top level WORKSPACE.
-		files = append(files, newFile("", "WORKSPACE", ""))
-
-		// Used to denote that the top level directory is a package.
-		files = append(files, newFile("", GeneratedBuildFileName, ""))
-
-		files = append(files, newFile(bazelRulesSubDir, GeneratedBuildFileName, ""))
-
-		// These files are only used for queryview.
-		files = append(files, newFile(bazelRulesSubDir, "providers.bzl", providersBzl))
-
-		for bzlFileName, ruleShim := range ruleShims {
-			files = append(files, newFile(bazelRulesSubDir, bzlFileName+".bzl", ruleShim.content))
-		}
-		files = append(files, newFile(bazelRulesSubDir, "soong_module.bzl", generateSoongModuleBzl(ruleShims)))
-	}
-
-	files = append(files, createBuildFiles(buildToTargets, mode)...)
-
-	return files
-}
-
-func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
-	files := make([]BazelFile, 0, len(buildToTargets))
-	for _, dir := range android.SortedKeys(buildToTargets) {
-		targets := buildToTargets[dir]
-		targets.sort()
-
-		var content string
-		if mode == QueryView {
-			content = soongModuleLoad
-		}
-		if content != "" {
-			// If there are load statements, add a couple of newlines.
-			content += "\n\n"
-		}
-		content += targets.String()
-		files = append(files, newFile(dir, GeneratedBuildFileName, content))
-	}
-	return files
-}
-
-func newFile(dir, basename, content string) BazelFile {
-	return BazelFile{
-		Dir:      dir,
-		Basename: basename,
-		Contents: content,
-	}
-}
-
-const (
-	bazelRulesSubDir = "build/bazel/queryview_rules"
-)
-
-var (
-	// Certain module property names are blocklisted/ignored here, for the reasons commented.
-	ignoredPropNames = map[string]bool{
-		"name":               true, // redundant, since this is explicitly generated for every target
-		"from":               true, // reserved keyword
-		"in":                 true, // reserved keyword
-		"size":               true, // reserved for tests
-		"arch":               true, // interface prop type is not supported yet.
-		"multilib":           true, // interface prop type is not supported yet.
-		"target":             true, // interface prop type is not supported yet.
-		"visibility":         true, // Bazel has native visibility semantics. Handle later.
-		"features":           true, // There is already a built-in attribute 'features' which cannot be overridden.
-		"for":                true, // reserved keyword, b/233579439
-		"versions_with_info": true, // TODO(b/245730552) struct properties not fully supported
-	}
-)
-
-func shouldGenerateAttribute(prop string) bool {
-	return !ignoredPropNames[prop]
-}
-
-func shouldSkipStructField(field reflect.StructField) bool {
-	if field.PkgPath != "" && !field.Anonymous {
-		// Skip unexported fields. Some properties are
-		// internal to Soong only, and these fields do not have PkgPath.
-		return true
-	}
-	// fields with tag `blueprint:"mutated"` are exported to enable modification in mutators, etc.
-	// but cannot be set in a .bp file
-	if proptools.HasTag(field, "blueprint", "mutated") {
-		return true
-	}
-	return false
-}
-
-// FIXME(b/168089390): In Bazel, rules ending with "_test" needs to be marked as
-// testonly = True, forcing other rules that depend on _test rules to also be
-// marked as testonly = True. This semantic constraint is not present in Soong.
-// To work around, rename "*_test" rules to "*_test_".
-func canonicalizeModuleType(moduleName string) string {
-	if strings.HasSuffix(moduleName, "_test") {
-		return moduleName + "_"
-	}
-
-	return moduleName
-}
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
deleted file mode 100644
index 2f806fa..0000000
--- a/bp2build/conversion_test.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package bp2build
-
-import (
-	"sort"
-	"testing"
-)
-
-type bazelFilepath struct {
-	dir      string
-	basename string
-}
-
-func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) {
-	files := CreateBazelFiles(map[string]RuleShim{}, map[string]BazelTargets{}, QueryView)
-	expectedFilePaths := []bazelFilepath{
-		{
-			dir:      "",
-			basename: "BUILD.bazel",
-		},
-		{
-			dir:      "",
-			basename: "WORKSPACE",
-		},
-		{
-			dir:      bazelRulesSubDir,
-			basename: "BUILD.bazel",
-		},
-		{
-			dir:      bazelRulesSubDir,
-			basename: "providers.bzl",
-		},
-		{
-			dir:      bazelRulesSubDir,
-			basename: "soong_module.bzl",
-		},
-	}
-
-	// Compare number of files
-	if a, e := len(files), len(expectedFilePaths); a != e {
-		t.Errorf("Expected %d files, got %d", e, a)
-	}
-
-	// Sort the files to be deterministic
-	sort.Slice(files, func(i, j int) bool {
-		if dir1, dir2 := files[i].Dir, files[j].Dir; dir1 == dir2 {
-			return files[i].Basename < files[j].Basename
-		} else {
-			return dir1 < dir2
-		}
-	})
-
-	// Compare the file contents
-	for i := range files {
-		actualFile, expectedFile := files[i], expectedFilePaths[i]
-
-		if actualFile.Dir != expectedFile.dir || actualFile.Basename != expectedFile.basename {
-			t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
-		} else if actualFile.Basename == "BUILD.bazel" || actualFile.Basename == "WORKSPACE" {
-			if actualFile.Contents != "" {
-				t.Errorf("Expected %s to have no content.", actualFile)
-			}
-		} else if actualFile.Contents == "" {
-			t.Errorf("Contents of %s unexpected empty.", actualFile)
-		}
-	}
-}
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 8679821..3b7073e 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -109,41 +109,41 @@
 
 var _ android.ImageInterface = (*bpf)(nil)
 
-func (bpf *bpf) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (bpf *bpf) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
 
-func (bpf *bpf) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(bpf.properties.Vendor)
 }
 
-func (bpf *bpf) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (bpf *bpf) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return !proptools.Bool(bpf.properties.Vendor)
 }
 
-func (bpf *bpf) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (bpf *bpf) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (bpf *bpf) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (bpf *bpf) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
 	return nil
 }
 
-func (bpf *bpf) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (bpf *bpf) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
 	bpf.properties.VendorInternal = variation == "vendor"
 }
 
diff --git a/bpf/libbpf/libbpf_prog.go b/bpf/libbpf/libbpf_prog.go
index ac61510..0ca7af1 100644
--- a/bpf/libbpf/libbpf_prog.go
+++ b/bpf/libbpf/libbpf_prog.go
@@ -104,41 +104,41 @@
 
 var _ android.ImageInterface = (*libbpfProg)(nil)
 
-func (libbpf *libbpfProg) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (libbpf *libbpfProg) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
 
-func (libbpf *libbpfProg) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (libbpf *libbpfProg) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (libbpf *libbpfProg) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return true
 }
 
-func (libbpf *libbpfProg) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (libbpf *libbpfProg) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (libbpf *libbpfProg) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (libbpf *libbpfProg) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (libbpf *libbpfProg) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (libbpf *libbpfProg) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
 	return nil
 }
 
-func (libbpf *libbpfProg) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (libbpf *libbpfProg) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
 }
 
 func (libbpf *libbpfProg) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/bpf/libbpf/libbpf_prog_test.go b/bpf/libbpf/libbpf_prog_test.go
index f4f5167..7f3653d 100644
--- a/bpf/libbpf/libbpf_prog_test.go
+++ b/bpf/libbpf/libbpf_prog_test.go
@@ -47,6 +47,7 @@
 
 		cc_test {
 			name: "vts_test_binary_bpf_module",
+			compile_multilib: "first",
 			srcs: ["BpfTest.cpp"],
 			data: [":bpf.o"],
 			gtest: false,
diff --git a/build_test.bash b/build_test.bash
deleted file mode 100755
index defdd82..0000000
--- a/build_test.bash
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash -eu
-#
-# Copyright 2017 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# This file is used in our continous build infrastructure to run a variety of
-# tests related to the build system.
-#
-# Currently, it's used to build and run multiproduct_kati, so it'll attempt
-# to build ninja files for every product in the tree. I expect this to
-# evolve as we find interesting things to test or track performance for.
-#
-
-# Products that are broken or otherwise don't work with multiproduct_kati
-SKIPPED_PRODUCTS=(
-    # These products are for soong-only builds, and will fail the kati stage.
-    linux_bionic
-    mainline_sdk
-    ndk
-
-    # New architecture bringup, fails without ALLOW_MISSING_DEPENDENCIES=true
-    aosp_riscv64
-)
-
-# To track how long we took to startup.
-case $(uname -s) in
-  Darwin)
-    export TRACE_BEGIN_SOONG=`$T/prebuilts/build-tools/path/darwin-x86/date +%s%3N`
-    ;;
-  *)
-    export TRACE_BEGIN_SOONG=$(date +%s%N)
-    ;;
-esac
-
-# Remove BUILD_NUMBER so that incremental builds on build servers don't
-# re-read makefiles every time.
-unset BUILD_NUMBER
-
-export TOP=$(cd $(dirname ${BASH_SOURCE[0]})/../..; PWD= /bin/pwd)
-cd "${TOP}"
-source "${TOP}/build/soong/scripts/microfactory.bash"
-
-case $(uname) in
-  Linux)
-    if [[ -f /lib/x86_64-linux-gnu/libSegFault.so ]]; then
-      export LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so
-      export SEGFAULT_USE_ALTSTACK=1
-    fi
-    ulimit -a
-    ;;
-esac
-
-echo
-echo "Free disk space:"
-# Ignore df errors because it errors out on gvfsd file systems
-# but still displays most of the useful info we need
-df -h || true
-
-echo
-echo "Running Bazel smoke test..."
-STANDALONE_BAZEL=true "${TOP}/build/bazel/bin/bazel" --batch --max_idle_secs=1 help
-
-echo
-echo "Running Soong test..."
-soong_build_go multiproduct_kati android/soong/cmd/multiproduct_kati
-exec "$(getoutdir)/multiproduct_kati" --skip-products "$(echo "${SKIPPED_PRODUCTS[@]-}" | tr ' ' ',')" "$@"
diff --git a/cc/cc.go b/cc/cc.go
index 9c514ee..52bf669 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -119,9 +119,10 @@
 
 	ObjFiles []string
 
-	GeneratedSources []string
-	GeneratedHeaders []string
-	GeneratedDeps    []string
+	GeneratedSources            []string
+	GeneratedHeaders            []string
+	DeviceFirstGeneratedHeaders []string
+	GeneratedDeps               []string
 
 	ReexportGeneratedHeaders []string
 
@@ -2609,6 +2610,11 @@
 		actx.AddDependency(c, depTag, gen)
 	}
 
+	for _, gen := range deps.DeviceFirstGeneratedHeaders {
+		depTag := genHeaderDepTag
+		actx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), depTag, gen)
+	}
+
 	crtVariations := GetCrtVariations(ctx, c)
 	actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...)
 	for _, crt := range deps.CrtBegin {
diff --git a/cc/compiler.go b/cc/compiler.go
index e49de6f..f06287c 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -100,6 +100,11 @@
 	// of genrule modules.
 	Generated_headers proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
 
+	// Same as generated_headers, but the dependencies will be added based on the first supported
+	// arch variant and the device os variant. This can be useful for creating a host tool that
+	// embeds a copy of a device tool, that it then extracts and pushes to a device at runtime.
+	Device_first_generated_headers proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
+
 	// pass -frtti instead of -fno-rtti
 	Rtti *bool `android:"arch_variant"`
 
@@ -294,6 +299,7 @@
 	deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
 	deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources)
 	deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers.GetOrDefault(ctx, nil)...)
+	deps.DeviceFirstGeneratedHeaders = append(deps.DeviceFirstGeneratedHeaders, compiler.Properties.Device_first_generated_headers.GetOrDefault(ctx, nil)...)
 	deps.AidlLibs = append(deps.AidlLibs, compiler.Properties.Aidl.Libs...)
 
 	android.ProtoDeps(ctx, &compiler.Proto)
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 0aa9d4b..8a974c0 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -347,6 +347,7 @@
 
 func PackageFuzzModule(ctx android.ModuleContext, fuzzPackagedModule fuzz.FuzzPackagedModule, pctx android.PackageContext) fuzz.FuzzPackagedModule {
 	fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Corpus)
+	fuzzPackagedModule.Corpus = append(fuzzPackagedModule.Corpus, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_common_corpus)...)
 
 	fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Data)
 
diff --git a/cc/genrule.go b/cc/genrule.go
index fe3b127..bd6c5f1 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -77,41 +77,41 @@
 
 var _ android.ImageInterface = (*GenruleExtraProperties)(nil)
 
-func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
 
-func (g *GenruleExtraProperties) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return Bool(g.Vendor_available) || Bool(g.Odm_available) || ctx.SocSpecific() || ctx.DeviceSpecific()
 }
 
-func (g *GenruleExtraProperties) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return Bool(g.Product_available) || ctx.ProductSpecific()
 }
 
-func (g *GenruleExtraProperties) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return !(ctx.SocSpecific() || ctx.DeviceSpecific() || ctx.ProductSpecific())
 }
 
-func (g *GenruleExtraProperties) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return Bool(g.Ramdisk_available)
 }
 
-func (g *GenruleExtraProperties) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return Bool(g.Vendor_ramdisk_available)
 }
 
-func (g *GenruleExtraProperties) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	// If the build is using a snapshot, the recovery variant under AOSP directories
 	// is not needed.
 	return Bool(g.Recovery_available)
 }
 
-func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
 	return nil
 }
 
-func (g *GenruleExtraProperties) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (g *GenruleExtraProperties) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
 }
diff --git a/cc/image.go b/cc/image.go
index 7594a08..ee40483 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -177,7 +177,7 @@
 	IsSnapshotPrebuilt() bool
 
 	// SnapshotVersion returns the snapshot version for this module.
-	SnapshotVersion(mctx android.BaseModuleContext) string
+	SnapshotVersion(mctx android.ImageInterfaceContext) string
 
 	// SdkVersion returns the SDK version for this module.
 	SdkVersion() string
@@ -209,7 +209,7 @@
 
 var _ ImageMutatableModule = (*Module)(nil)
 
-func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
+func (m *Module) ImageMutatorBegin(mctx android.ImageInterfaceContext) {
 	MutateImage(mctx, m)
 }
 
@@ -273,7 +273,7 @@
 	m.Properties.VendorVariantNeeded = b
 }
 
-func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
+func (m *Module) SnapshotVersion(mctx android.ImageInterfaceContext) string {
 	if snapshot, ok := m.linker.(SnapshotInterface); ok {
 		return snapshot.Version()
 	} else {
@@ -291,7 +291,7 @@
 }
 
 // MutateImage handles common image mutations for ImageMutatableModule interfaces.
-func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
+func MutateImage(mctx android.ImageInterfaceContext, m ImageMutatableModule) {
 	// Validation check
 	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
 	productSpecific := mctx.ProductSpecific()
@@ -431,35 +431,35 @@
 	}
 }
 
-func (c *Module) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return c.Properties.VendorVariantNeeded
 }
 
-func (c *Module) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return c.Properties.ProductVariantNeeded
 }
 
-func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return c.Properties.CoreVariantNeeded
 }
 
-func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return c.Properties.RamdiskVariantNeeded
 }
 
-func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return c.Properties.VendorRamdiskVariantNeeded
 }
 
-func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return c.Properties.RecoveryVariantNeeded
 }
 
-func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (c *Module) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
 	return c.Properties.ExtraVersionedImageVariations
 }
 
@@ -513,7 +513,7 @@
 	}
 }
 
-func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string) {
+func (c *Module) SetImageVariation(ctx android.ImageInterfaceContext, variant string) {
 	if variant == android.RamdiskVariation {
 		c.MakeAsPlatform()
 		squashRamdiskSrcs(c)
diff --git a/cc/test.go b/cc/test.go
index f5bb761..ae73886 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -15,10 +15,11 @@
 package cc
 
 import (
-	"github.com/google/blueprint/proptools"
 	"path/filepath"
 	"strconv"
 
+	"github.com/google/blueprint/proptools"
+
 	"android/soong/android"
 	"android/soong/tradefed"
 )
@@ -82,6 +83,16 @@
 	// the test
 	Data []string `android:"path,arch_variant"`
 
+	// Same as data, but adds depedencies on modules using the device's os variant, and common
+	// architecture's variant. Can be useful to add device-built apps to the data of a host
+	// test.
+	Device_common_data []string `android:"path_device_common"`
+
+	// Same as data, but adds depedencies on modules using the device's os variant, and the device's
+	// first architecture's variant. Can be useful to add device-built apps to the data of a host
+	// test.
+	Device_first_data []string `android:"path_device_first"`
+
 	// list of shared library modules that should be installed alongside the test
 	Data_libs []string `android:"arch_variant"`
 
@@ -324,6 +335,8 @@
 
 func (test *testBinary) install(ctx ModuleContext, file android.Path) {
 	dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
+	dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...)
+	dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_first_data)...)
 
 	for _, dataSrcPath := range dataSrcPaths {
 		test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
diff --git a/cmd/multiproduct_kati/Android.bp b/cmd/multiproduct_kati/Android.bp
deleted file mode 100644
index 20ca2a3..0000000
--- a/cmd/multiproduct_kati/Android.bp
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-blueprint_go_binary {
-    name: "multiproduct_kati",
-    deps: [
-        "soong-ui-logger",
-        "soong-ui-signal",
-        "soong-ui-terminal",
-        "soong-ui-tracer",
-        "soong-zip",
-    ],
-    srcs: [
-        "main.go",
-    ],
-    testSrcs: [
-        "main_test.go",
-    ],
-    linux: {
-        srcs: [
-            "main_linux.go",
-        ],
-    },
-    darwin: {
-        srcs: [
-            "main_darwin.go",
-        ],
-    },
-}
diff --git a/cmd/multiproduct_kati/main.go b/cmd/multiproduct_kati/main.go
deleted file mode 100644
index c3b0381..0000000
--- a/cmd/multiproduct_kati/main.go
+++ /dev/null
@@ -1,598 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"bufio"
-	"context"
-	"flag"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"regexp"
-	"runtime"
-	"strings"
-	"sync"
-	"syscall"
-	"time"
-
-	"android/soong/ui/logger"
-	"android/soong/ui/signal"
-	"android/soong/ui/status"
-	"android/soong/ui/terminal"
-	"android/soong/ui/tracer"
-	"android/soong/zip"
-)
-
-var numJobs = flag.Int("j", 0, "number of parallel jobs [0=autodetect]")
-
-var keepArtifacts = flag.Bool("keep", false, "keep archives of artifacts")
-var incremental = flag.Bool("incremental", false, "run in incremental mode (saving intermediates)")
-
-var outDir = flag.String("out", "", "path to store output directories (defaults to tmpdir under $OUT when empty)")
-var alternateResultDir = flag.Bool("dist", false, "write select results to $DIST_DIR (or <out>/dist when empty)")
-
-var bazelMode = flag.Bool("bazel-mode", false, "use bazel for analysis of certain modules")
-var bazelModeStaging = flag.Bool("bazel-mode-staging", false, "use bazel for analysis of certain near-ready modules")
-
-var onlyConfig = flag.Bool("only-config", false, "Only run product config (not Soong or Kati)")
-var onlySoong = flag.Bool("only-soong", false, "Only run product config and Soong (not Kati)")
-
-var buildVariant = flag.String("variant", "eng", "build variant to use")
-
-var shardCount = flag.Int("shard-count", 1, "split the products into multiple shards (to spread the build onto multiple machines, etc)")
-var shard = flag.Int("shard", 1, "1-indexed shard to execute")
-
-var skipProducts multipleStringArg
-var includeProducts multipleStringArg
-
-func init() {
-	flag.Var(&skipProducts, "skip-products", "comma-separated list of products to skip (known failures, etc)")
-	flag.Var(&includeProducts, "products", "comma-separated list of products to build")
-}
-
-// multipleStringArg is a flag.Value that takes comma separated lists and converts them to a
-// []string.  The argument can be passed multiple times to append more values.
-type multipleStringArg []string
-
-func (m *multipleStringArg) String() string {
-	return strings.Join(*m, `, `)
-}
-
-func (m *multipleStringArg) Set(s string) error {
-	*m = append(*m, strings.Split(s, ",")...)
-	return nil
-}
-
-const errorLeadingLines = 20
-const errorTrailingLines = 20
-
-func errMsgFromLog(filename string) string {
-	if filename == "" {
-		return ""
-	}
-
-	data, err := ioutil.ReadFile(filename)
-	if err != nil {
-		return ""
-	}
-
-	lines := strings.Split(strings.TrimSpace(string(data)), "\n")
-	if len(lines) > errorLeadingLines+errorTrailingLines+1 {
-		lines[errorLeadingLines] = fmt.Sprintf("... skipping %d lines ...",
-			len(lines)-errorLeadingLines-errorTrailingLines)
-
-		lines = append(lines[:errorLeadingLines+1],
-			lines[len(lines)-errorTrailingLines:]...)
-	}
-	var buf strings.Builder
-	for _, line := range lines {
-		buf.WriteString("> ")
-		buf.WriteString(line)
-		buf.WriteString("\n")
-	}
-	return buf.String()
-}
-
-// TODO(b/70370883): This tool uses a lot of open files -- over the default
-// soft limit of 1024 on some systems. So bump up to the hard limit until I fix
-// the algorithm.
-func setMaxFiles(log logger.Logger) {
-	var limits syscall.Rlimit
-
-	err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limits)
-	if err != nil {
-		log.Println("Failed to get file limit:", err)
-		return
-	}
-
-	log.Verbosef("Current file limits: %d soft, %d hard", limits.Cur, limits.Max)
-	if limits.Cur == limits.Max {
-		return
-	}
-
-	limits.Cur = limits.Max
-	err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limits)
-	if err != nil {
-		log.Println("Failed to increase file limit:", err)
-	}
-}
-
-func inList(str string, list []string) bool {
-	for _, other := range list {
-		if str == other {
-			return true
-		}
-	}
-	return false
-}
-
-func copyFile(from, to string) error {
-	fromFile, err := os.Open(from)
-	if err != nil {
-		return err
-	}
-	defer fromFile.Close()
-
-	toFile, err := os.Create(to)
-	if err != nil {
-		return err
-	}
-	defer toFile.Close()
-
-	_, err = io.Copy(toFile, fromFile)
-	return err
-}
-
-type mpContext struct {
-	Logger logger.Logger
-	Status status.ToolStatus
-
-	SoongUi     string
-	MainOutDir  string
-	MainLogsDir string
-}
-
-func findNamedProducts(soongUi string, log logger.Logger) []string {
-	cmd := exec.Command(soongUi, "--dumpvars-mode", "--vars=all_named_products")
-	output, err := cmd.Output()
-	if err != nil {
-		log.Fatalf("Cannot determine named products: %v", err)
-	}
-
-	rx := regexp.MustCompile(`^all_named_products='(.*)'$`)
-	match := rx.FindStringSubmatch(strings.TrimSpace(string(output)))
-	return strings.Fields(match[1])
-}
-
-// ensureEmptyFileExists ensures that the containing directory exists, and the
-// specified file exists. If it doesn't exist, it will write an empty file.
-func ensureEmptyFileExists(file string, log logger.Logger) {
-	if _, err := os.Stat(file); os.IsNotExist(err) {
-		f, err := os.Create(file)
-		if err != nil {
-			log.Fatalf("Error creating %s: %q\n", file, err)
-		}
-		f.Close()
-	} else if err != nil {
-		log.Fatalf("Error checking %s: %q\n", file, err)
-	}
-}
-
-func outDirBase() string {
-	outDirBase := os.Getenv("OUT_DIR")
-	if outDirBase == "" {
-		return "out"
-	} else {
-		return outDirBase
-	}
-}
-
-func distDir(outDir string) string {
-	if distDir := os.Getenv("DIST_DIR"); distDir != "" {
-		return filepath.Clean(distDir)
-	} else {
-		return filepath.Join(outDir, "dist")
-	}
-}
-
-func forceAnsiOutput() bool {
-	value := os.Getenv("SOONG_UI_ANSI_OUTPUT")
-	return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true"
-}
-
-func getBazelArg() string {
-	count := 0
-	str := ""
-	if *bazelMode {
-		count++
-		str = "--bazel-mode"
-	}
-	if *bazelModeStaging {
-		count++
-		str = "--bazel-mode-staging"
-	}
-
-	if count > 1 {
-		// Can't set more than one
-		fmt.Errorf("Only one bazel mode is permitted to be set.")
-		os.Exit(1)
-	}
-
-	return str
-}
-
-func main() {
-	stdio := terminal.StdioImpl{}
-
-	output := terminal.NewStatusOutput(stdio.Stdout(), "", false, false,
-		forceAnsiOutput())
-	log := logger.New(output)
-	defer log.Cleanup()
-
-	for _, v := range os.Environ() {
-		log.Println("Environment: " + v)
-	}
-
-	log.Printf("Argv: %v\n", os.Args)
-
-	flag.Parse()
-
-	_, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	trace := tracer.New(log)
-	defer trace.Close()
-
-	stat := &status.Status{}
-	defer stat.Finish()
-	stat.AddOutput(output)
-
-	var failures failureCount
-	stat.AddOutput(&failures)
-
-	signal.SetupSignals(log, cancel, func() {
-		trace.Close()
-		log.Cleanup()
-		stat.Finish()
-	})
-
-	soongUi := "build/soong/soong_ui.bash"
-
-	var outputDir string
-	if *outDir != "" {
-		outputDir = *outDir
-	} else {
-		name := "multiproduct"
-		if !*incremental {
-			name += "-" + time.Now().Format("20060102150405")
-		}
-		outputDir = filepath.Join(outDirBase(), name)
-	}
-
-	log.Println("Output directory:", outputDir)
-
-	// The ninja_build file is used by our buildbots to understand that the output
-	// can be parsed as ninja output.
-	if err := os.MkdirAll(outputDir, 0777); err != nil {
-		log.Fatalf("Failed to create output directory: %v", err)
-	}
-	ensureEmptyFileExists(filepath.Join(outputDir, "ninja_build"), log)
-
-	logsDir := filepath.Join(outputDir, "logs")
-	os.MkdirAll(logsDir, 0777)
-
-	var configLogsDir string
-	if *alternateResultDir {
-		configLogsDir = filepath.Join(distDir(outDirBase()), "logs")
-	} else {
-		configLogsDir = outputDir
-	}
-
-	log.Println("Logs dir: " + configLogsDir)
-
-	os.MkdirAll(configLogsDir, 0777)
-	log.SetOutput(filepath.Join(configLogsDir, "soong.log"))
-	trace.SetOutput(filepath.Join(configLogsDir, "build.trace"))
-
-	var jobs = *numJobs
-	if jobs < 1 {
-		jobs = runtime.NumCPU() / 4
-
-		ramGb := int(detectTotalRAM() / (1024 * 1024 * 1024))
-		if ramJobs := ramGb / 40; ramGb > 0 && jobs > ramJobs {
-			jobs = ramJobs
-		}
-
-		if jobs < 1 {
-			jobs = 1
-		}
-	}
-	log.Verbosef("Using %d parallel jobs", jobs)
-
-	setMaxFiles(log)
-
-	allProducts := findNamedProducts(soongUi, log)
-	var productsList []string
-
-	if len(includeProducts) > 0 {
-		var missingProducts []string
-		for _, product := range includeProducts {
-			if inList(product, allProducts) {
-				productsList = append(productsList, product)
-			} else {
-				missingProducts = append(missingProducts, product)
-			}
-		}
-		if len(missingProducts) > 0 {
-			log.Fatalf("Products don't exist: %s\n", missingProducts)
-		}
-	} else {
-		productsList = allProducts
-	}
-
-	finalProductsList := make([]string, 0, len(productsList))
-	skipProduct := func(p string) bool {
-		for _, s := range skipProducts {
-			if p == s {
-				return true
-			}
-		}
-		return false
-	}
-	for _, product := range productsList {
-		if !skipProduct(product) {
-			finalProductsList = append(finalProductsList, product)
-		} else {
-			log.Verbose("Skipping: ", product)
-		}
-	}
-
-	if *shard < 1 {
-		log.Fatalf("--shard value must be >= 1, not %d\n", *shard)
-	} else if *shardCount < 1 {
-		log.Fatalf("--shard-count value must be >= 1, not %d\n", *shardCount)
-	} else if *shard > *shardCount {
-		log.Fatalf("--shard (%d) must not be greater than --shard-count (%d)\n", *shard,
-			*shardCount)
-	} else if *shardCount > 1 {
-		finalProductsList = splitList(finalProductsList, *shardCount)[*shard-1]
-	}
-
-	log.Verbose("Got product list: ", finalProductsList)
-
-	s := stat.StartTool()
-	s.SetTotalActions(len(finalProductsList))
-
-	mpCtx := &mpContext{
-		Logger:      log,
-		Status:      s,
-		SoongUi:     soongUi,
-		MainOutDir:  outputDir,
-		MainLogsDir: logsDir,
-	}
-
-	products := make(chan string, len(productsList))
-	go func() {
-		defer close(products)
-		for _, product := range finalProductsList {
-			products <- product
-		}
-	}()
-
-	var wg sync.WaitGroup
-	for i := 0; i < jobs; i++ {
-		wg.Add(1)
-		// To smooth out the spikes in memory usage, skew the
-		// initial starting time of the jobs by a small amount.
-		time.Sleep(15 * time.Second)
-		go func() {
-			defer wg.Done()
-			for {
-				select {
-				case product := <-products:
-					if product == "" {
-						return
-					}
-					runSoongUiForProduct(mpCtx, product)
-				}
-			}
-		}()
-	}
-	wg.Wait()
-
-	if *alternateResultDir {
-		args := zip.ZipArgs{
-			FileArgs: []zip.FileArg{
-				{GlobDir: logsDir, SourcePrefixToStrip: logsDir},
-			},
-			OutputFilePath:   filepath.Join(distDir(outDirBase()), "logs.zip"),
-			NumParallelJobs:  runtime.NumCPU(),
-			CompressionLevel: 5,
-		}
-		log.Printf("Logs zip: %v\n", args.OutputFilePath)
-		if err := zip.Zip(args); err != nil {
-			log.Fatalf("Error zipping logs: %v", err)
-		}
-	}
-
-	s.Finish()
-
-	if failures.count == 1 {
-		log.Fatal("1 failure")
-	} else if failures.count > 1 {
-		log.Fatalf("%d failures %q", failures.count, failures.fails)
-	} else {
-		fmt.Fprintln(output, "Success")
-	}
-}
-
-func cleanupAfterProduct(outDir, productZip string) {
-	if *keepArtifacts {
-		args := zip.ZipArgs{
-			FileArgs: []zip.FileArg{
-				{
-					GlobDir:             outDir,
-					SourcePrefixToStrip: outDir,
-				},
-			},
-			OutputFilePath:   productZip,
-			NumParallelJobs:  runtime.NumCPU(),
-			CompressionLevel: 5,
-		}
-		if err := zip.Zip(args); err != nil {
-			log.Fatalf("Error zipping artifacts: %v", err)
-		}
-	}
-	if !*incremental {
-		os.RemoveAll(outDir)
-	}
-}
-
-func runSoongUiForProduct(mpctx *mpContext, product string) {
-	outDir := filepath.Join(mpctx.MainOutDir, product)
-	logsDir := filepath.Join(mpctx.MainLogsDir, product)
-	productZip := filepath.Join(mpctx.MainOutDir, product+".zip")
-	consoleLogPath := filepath.Join(logsDir, "std.log")
-
-	if err := os.MkdirAll(outDir, 0777); err != nil {
-		mpctx.Logger.Fatalf("Error creating out directory: %v", err)
-	}
-	if err := os.MkdirAll(logsDir, 0777); err != nil {
-		mpctx.Logger.Fatalf("Error creating log directory: %v", err)
-	}
-
-	consoleLogFile, err := os.Create(consoleLogPath)
-	if err != nil {
-		mpctx.Logger.Fatalf("Error creating console log file: %v", err)
-	}
-	defer consoleLogFile.Close()
-
-	consoleLogWriter := bufio.NewWriter(consoleLogFile)
-	defer consoleLogWriter.Flush()
-
-	args := []string{"--make-mode", "--skip-soong-tests", "--skip-ninja"}
-
-	if !*keepArtifacts {
-		args = append(args, "--empty-ninja-file")
-	}
-
-	if *onlyConfig {
-		args = append(args, "--config-only")
-	} else if *onlySoong {
-		args = append(args, "--soong-only")
-	}
-
-	bazelStr := getBazelArg()
-	if bazelStr != "" {
-		args = append(args, bazelStr)
-	}
-
-	cmd := exec.Command(mpctx.SoongUi, args...)
-	cmd.Stdout = consoleLogWriter
-	cmd.Stderr = consoleLogWriter
-	cmd.Env = append(os.Environ(),
-		"OUT_DIR="+outDir,
-		"TARGET_PRODUCT="+product,
-		"TARGET_BUILD_VARIANT="+*buildVariant,
-		"TARGET_BUILD_TYPE=release",
-		"TARGET_BUILD_APPS=",
-		"TARGET_BUILD_UNBUNDLED=",
-		"USE_RBE=false") // Disabling RBE saves ~10 secs per product
-
-	if *alternateResultDir {
-		cmd.Env = append(cmd.Env,
-			"DIST_DIR="+filepath.Join(distDir(outDirBase()), "products/"+product))
-	}
-
-	action := &status.Action{
-		Description: product,
-		Outputs:     []string{product},
-	}
-
-	mpctx.Status.StartAction(action)
-	defer cleanupAfterProduct(outDir, productZip)
-
-	before := time.Now()
-	err = cmd.Run()
-
-	if !*onlyConfig && !*onlySoong {
-		katiBuildNinjaFile := filepath.Join(outDir, "build-"+product+".ninja")
-		if after, err := os.Stat(katiBuildNinjaFile); err == nil && after.ModTime().After(before) {
-			err := copyFile(consoleLogPath, filepath.Join(filepath.Dir(consoleLogPath), "std_full.log"))
-			if err != nil {
-				log.Fatalf("Error copying log file: %s", err)
-			}
-		}
-	}
-	var errOutput string
-	if err == nil {
-		errOutput = ""
-	} else {
-		errOutput = errMsgFromLog(consoleLogPath)
-	}
-
-	mpctx.Status.FinishAction(status.ActionResult{
-		Action: action,
-		Error:  err,
-		Output: errOutput,
-	})
-}
-
-type failureCount struct {
-	count int
-	fails []string
-}
-
-func (f *failureCount) StartAction(action *status.Action, counts status.Counts) {}
-
-func (f *failureCount) FinishAction(result status.ActionResult, counts status.Counts) {
-	if result.Error != nil {
-		f.count += 1
-		f.fails = append(f.fails, result.Action.Description)
-	}
-}
-
-func (f *failureCount) Message(level status.MsgLevel, message string) {
-	if level >= status.ErrorLvl {
-		f.count += 1
-	}
-}
-
-func (f *failureCount) Flush() {}
-
-func (f *failureCount) Write(p []byte) (int, error) {
-	// discard writes
-	return len(p), nil
-}
-
-func splitList(list []string, shardCount int) (ret [][]string) {
-	each := len(list) / shardCount
-	extra := len(list) % shardCount
-	for i := 0; i < shardCount; i++ {
-		count := each
-		if extra > 0 {
-			count += 1
-			extra -= 1
-		}
-		ret = append(ret, list[:count])
-		list = list[count:]
-	}
-	return
-}
diff --git a/cmd/multiproduct_kati/main_darwin.go b/cmd/multiproduct_kati/main_darwin.go
deleted file mode 100644
index 3d1b12a..0000000
--- a/cmd/multiproduct_kati/main_darwin.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-func detectTotalRAM() uint64 {
-	// unimplemented stub on darwin
-	return 0
-}
diff --git a/cmd/multiproduct_kati/main_linux.go b/cmd/multiproduct_kati/main_linux.go
deleted file mode 100644
index db74496..0000000
--- a/cmd/multiproduct_kati/main_linux.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"syscall"
-)
-
-func detectTotalRAM() uint64 {
-	var info syscall.Sysinfo_t
-	err := syscall.Sysinfo(&info)
-	if err != nil {
-		panic(err)
-	}
-	return info.Totalram * uint64(info.Unit)
-}
diff --git a/cmd/multiproduct_kati/main_test.go b/cmd/multiproduct_kati/main_test.go
deleted file mode 100644
index 263a124..0000000
--- a/cmd/multiproduct_kati/main_test.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2019 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"fmt"
-	"reflect"
-	"testing"
-)
-
-func TestSplitList(t *testing.T) {
-	testcases := []struct {
-		inputCount int
-		shardCount int
-		want       [][]string
-	}{
-		{
-			inputCount: 1,
-			shardCount: 1,
-			want:       [][]string{{"1"}},
-		},
-		{
-			inputCount: 1,
-			shardCount: 2,
-			want:       [][]string{{"1"}, {}},
-		},
-		{
-			inputCount: 4,
-			shardCount: 2,
-			want:       [][]string{{"1", "2"}, {"3", "4"}},
-		},
-		{
-			inputCount: 19,
-			shardCount: 10,
-			want: [][]string{
-				{"1", "2"},
-				{"3", "4"},
-				{"5", "6"},
-				{"7", "8"},
-				{"9", "10"},
-				{"11", "12"},
-				{"13", "14"},
-				{"15", "16"},
-				{"17", "18"},
-				{"19"},
-			},
-		},
-		{
-			inputCount: 15,
-			shardCount: 10,
-			want: [][]string{
-				{"1", "2"},
-				{"3", "4"},
-				{"5", "6"},
-				{"7", "8"},
-				{"9", "10"},
-				{"11"},
-				{"12"},
-				{"13"},
-				{"14"},
-				{"15"},
-			},
-		},
-	}
-
-	for _, tc := range testcases {
-		t.Run(fmt.Sprintf("%d/%d", tc.inputCount, tc.shardCount), func(t *testing.T) {
-			input := []string{}
-			for i := 1; i <= tc.inputCount; i++ {
-				input = append(input, fmt.Sprintf("%d", i))
-			}
-
-			got := splitList(input, tc.shardCount)
-
-			if !reflect.DeepEqual(got, tc.want) {
-				t.Errorf("unexpected result for splitList([]string{...%d...}, %d):\nwant: %v\n got: %v\n",
-					tc.inputCount, tc.shardCount, tc.want, got)
-			}
-		})
-	}
-}
diff --git a/cmd/soong_build/Android.bp b/cmd/soong_build/Android.bp
index 72af3e0..d8f563b 100644
--- a/cmd/soong_build/Android.bp
+++ b/cmd/soong_build/Android.bp
@@ -26,13 +26,11 @@
         "soong",
         "soong-android",
         "soong-provenance",
-        "soong-bp2build",
         "soong-ui-metrics_proto",
     ],
     srcs: [
         "main.go",
         "writedocs.go",
-        "queryview.go",
     ],
     primaryBuilder: true,
 }
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 5b1ae54..6642023 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -26,7 +26,6 @@
 
 	"android/soong/android"
 	"android/soong/android/allowlists"
-	"android/soong/bp2build"
 	"android/soong/shared"
 
 	"github.com/google/blueprint"
@@ -78,7 +77,6 @@
 	flag.StringVar(&cmdlineArgs.ModuleGraphFile, "module_graph_file", "", "JSON module graph file to output")
 	flag.StringVar(&cmdlineArgs.ModuleActionsFile, "module_actions_file", "", "JSON file to output inputs/outputs of actions of modules")
 	flag.StringVar(&cmdlineArgs.DocFile, "soong_docs", "", "build documentation file to output")
-	flag.StringVar(&cmdlineArgs.BazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory relative to --top")
 	flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
 	flag.StringVar(&cmdlineArgs.SoongVariables, "soong_variables", "soong.variables", "the file contains all build variables")
 	flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
@@ -121,16 +119,6 @@
 	return false
 }
 
-// Run the code-generation phase to convert BazelTargetModules to BUILD files.
-func runQueryView(queryviewDir, queryviewMarker string, ctx *android.Context) {
-	ctx.EventHandler.Begin("queryview")
-	defer ctx.EventHandler.End("queryview")
-	codegenContext := bp2build.NewCodegenContext(ctx.Config(), ctx, bp2build.QueryView, topDir)
-	err := createBazelWorkspace(codegenContext, shared.JoinPath(topDir, queryviewDir), false)
-	maybeQuit(err, "")
-	touch(shared.JoinPath(topDir, queryviewMarker))
-}
-
 func writeNinjaHint(ctx *android.Context) error {
 	ctx.BeginEvent("ninja_hint")
 	defer ctx.EndEvent("ninja_hint")
@@ -283,7 +271,7 @@
 	switch ctx.Config().BuildMode {
 	case android.GenerateModuleGraph:
 		stopBefore = bootstrap.StopBeforeWriteNinja
-	case android.GenerateQueryView, android.GenerateDocFile:
+	case android.GenerateDocFile:
 		stopBefore = bootstrap.StopBeforePrepareBuildActions
 	default:
 		stopBefore = bootstrap.DoEverything
@@ -294,10 +282,6 @@
 
 	// Convert the Soong module graph into Bazel BUILD files.
 	switch ctx.Config().BuildMode {
-	case android.GenerateQueryView:
-		queryviewMarkerFile := cmdlineArgs.BazelQueryViewDir + ".marker"
-		runQueryView(cmdlineArgs.BazelQueryViewDir, queryviewMarkerFile, ctx)
-		return queryviewMarkerFile, ninjaDeps
 	case android.GenerateModuleGraph:
 		writeJsonModuleGraphAndActions(ctx, cmdlineArgs)
 		return cmdlineArgs.ModuleGraphFile, ninjaDeps
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
deleted file mode 100644
index eafd67a..0000000
--- a/cmd/soong_build/queryview.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2020 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-	"io/fs"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-
-	"android/soong/android"
-	"android/soong/bp2build"
-)
-
-// A helper function to generate a Read-only Bazel workspace in outDir
-func createBazelWorkspace(ctx *bp2build.CodegenContext, outDir string, generateFilegroups bool) error {
-	os.RemoveAll(outDir)
-	ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
-
-	res, err := bp2build.GenerateBazelTargets(ctx, generateFilegroups)
-	if err != nil {
-		panic(err)
-	}
-
-	filesToWrite := bp2build.CreateBazelFiles(ruleShims, res.BuildDirToTargets(), ctx.Mode())
-	bazelRcFiles, err2 := CopyBazelRcFiles()
-	if err2 != nil {
-		return err2
-	}
-	filesToWrite = append(filesToWrite, bazelRcFiles...)
-	for _, f := range filesToWrite {
-		if err := writeReadOnlyFile(outDir, f); err != nil {
-			return err
-		}
-	}
-
-	return nil
-}
-
-// CopyBazelRcFiles creates BazelFiles for all the bazelrc files under
-// build/bazel. They're needed because the rc files are still read when running
-// queryview, so they have to be in the queryview workspace.
-func CopyBazelRcFiles() ([]bp2build.BazelFile, error) {
-	result := make([]bp2build.BazelFile, 0)
-	err := filepath.WalkDir(filepath.Join(topDir, "build/bazel"), func(path string, info fs.DirEntry, err error) error {
-		if filepath.Ext(path) == ".bazelrc" {
-			contents, err := os.ReadFile(path)
-			if err != nil {
-				return err
-			}
-			path, err = filepath.Rel(topDir, path)
-			if err != nil {
-				return err
-			}
-			result = append(result, bp2build.BazelFile{
-				Dir:      filepath.Dir(path),
-				Basename: filepath.Base(path),
-				Contents: string(contents),
-			})
-		}
-		return nil
-	})
-	return result, err
-}
-
-// The auto-conversion directory should be read-only, sufficient for bazel query. The files
-// are not intended to be edited by end users.
-func writeReadOnlyFile(dir string, f bp2build.BazelFile) error {
-	dir = filepath.Join(dir, f.Dir)
-	if err := createDirectoryIfNonexistent(dir); err != nil {
-		return err
-	}
-	pathToFile := filepath.Join(dir, f.Basename)
-
-	// 0444 is read-only
-	err := ioutil.WriteFile(pathToFile, []byte(f.Contents), 0444)
-
-	return err
-}
-
-func writeReadWriteFile(dir string, f bp2build.BazelFile) error {
-	dir = filepath.Join(dir, f.Dir)
-	if err := createDirectoryIfNonexistent(dir); err != nil {
-		return err
-	}
-	pathToFile := filepath.Join(dir, f.Basename)
-
-	// 0644 is read-write
-	err := ioutil.WriteFile(pathToFile, []byte(f.Contents), 0644)
-
-	return err
-}
-
-func createDirectoryIfNonexistent(dir string) error {
-	if _, err := os.Stat(dir); os.IsNotExist(err) {
-		return os.MkdirAll(dir, os.ModePerm)
-	} else {
-		return err
-	}
-}
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 2d3156a..c7134d7 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -251,11 +251,10 @@
 	buildErrorFile := filepath.Join(logsDir, logsPrefix+"build_error")
 	rbeMetricsFile := filepath.Join(logsDir, logsPrefix+"rbe_metrics.pb")
 	soongMetricsFile := filepath.Join(logsDir, logsPrefix+"soong_metrics")
-	bp2buildMetricsFile := filepath.Join(logsDir, logsPrefix+"bp2build_metrics.pb")
 	soongBuildMetricsFile := filepath.Join(logsDir, logsPrefix+"soong_build_metrics.pb")
 
 	//Delete the stale metrics files
-	staleFileSlice := []string{buildErrorFile, rbeMetricsFile, soongMetricsFile, bp2buildMetricsFile, soongBuildMetricsFile}
+	staleFileSlice := []string{buildErrorFile, rbeMetricsFile, soongMetricsFile, soongBuildMetricsFile}
 	if err := deleteStaleMetrics(staleFileSlice); err != nil {
 		log.Fatalln(err)
 	}
diff --git a/cuj/Android.bp b/cuj/Android.bp
deleted file mode 100644
index f9cfdc1..0000000
--- a/cuj/Android.bp
+++ /dev/null
@@ -1,17 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-blueprint_go_binary {
-    name: "cuj_tests",
-    deps: [
-        "soong-ui-build",
-        "soong-ui-logger",
-        "soong-ui-signal",
-        "soong-ui-terminal",
-        "soong-ui-tracer",
-    ],
-    srcs: [
-        "cuj.go",
-    ],
-}
diff --git a/cuj/cuj.go b/cuj/cuj.go
deleted file mode 100644
index de6f10d..0000000
--- a/cuj/cuj.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2019 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This executable runs a series of build commands to test and benchmark some critical user journeys.
-package main
-
-import (
-	"context"
-	"fmt"
-	"os"
-	"path/filepath"
-	"strconv"
-	"strings"
-	"time"
-
-	"android/soong/ui/build"
-	"android/soong/ui/logger"
-	"android/soong/ui/metrics"
-	"android/soong/ui/signal"
-	"android/soong/ui/status"
-	"android/soong/ui/terminal"
-	"android/soong/ui/tracer"
-)
-
-type Test struct {
-	name   string
-	args   []string
-	before func() error
-
-	results TestResults
-}
-
-type TestResults struct {
-	metrics *metrics.Metrics
-	err     error
-}
-
-// Run runs a single build command.  It emulates the "m" command line by calling into Soong UI directly.
-func (t *Test) Run(logsDir string) {
-	output := terminal.NewStatusOutput(os.Stdout, "", false, false, false)
-
-	log := logger.New(output)
-	defer log.Cleanup()
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	trace := tracer.New(log)
-	defer trace.Close()
-
-	met := metrics.New()
-
-	stat := &status.Status{}
-	defer stat.Finish()
-	stat.AddOutput(output)
-	stat.AddOutput(trace.StatusTracer())
-
-	signal.SetupSignals(log, cancel, func() {
-		trace.Close()
-		log.Cleanup()
-		stat.Finish()
-	})
-
-	buildCtx := build.Context{ContextImpl: &build.ContextImpl{
-		Context: ctx,
-		Logger:  log,
-		Metrics: met,
-		Tracer:  trace,
-		Writer:  output,
-		Status:  stat,
-	}}
-
-	defer logger.Recover(func(err error) {
-		t.results.err = err
-	})
-
-	config := build.NewConfig(buildCtx, t.args...)
-	build.SetupOutDir(buildCtx, config)
-
-	os.MkdirAll(logsDir, 0777)
-	log.SetOutput(filepath.Join(logsDir, "soong.log"))
-	trace.SetOutput(filepath.Join(logsDir, "build.trace"))
-	stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, "verbose.log")))
-	stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, "error.log")))
-	stat.AddOutput(status.NewProtoErrorLog(log, filepath.Join(logsDir, "build_error")))
-	stat.AddOutput(status.NewCriticalPathLogger(log, nil))
-
-	defer met.Dump(filepath.Join(logsDir, "soong_metrics"))
-
-	if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok {
-		if !strings.HasSuffix(start, "N") {
-			if start_time, err := strconv.ParseUint(start, 10, 64); err == nil {
-				log.Verbosef("Took %dms to start up.",
-					time.Since(time.Unix(0, int64(start_time))).Nanoseconds()/time.Millisecond.Nanoseconds())
-				buildCtx.CompleteTrace(metrics.RunSetupTool, "startup", start_time, uint64(time.Now().UnixNano()))
-			}
-		}
-
-		if executable, err := os.Executable(); err == nil {
-			trace.ImportMicrofactoryLog(filepath.Join(filepath.Dir(executable), "."+filepath.Base(executable)+".trace"))
-		}
-	}
-
-	f := build.NewSourceFinder(buildCtx, config)
-	defer f.Shutdown()
-	build.FindSources(buildCtx, config, f)
-
-	build.Build(buildCtx, config)
-
-	t.results.metrics = met
-}
-
-// Touch the Intent.java file to cause a rebuild of the frameworks to monitor the
-// incremental build speed as mentioned b/152046247. Intent.java file was chosen
-// as it is a key component of the framework and is often modified.
-func touchIntentFile() error {
-	const intentFileName = "frameworks/base/core/java/android/content/Intent.java"
-	currentTime := time.Now().Local()
-	return os.Chtimes(intentFileName, currentTime, currentTime)
-}
-
-func main() {
-	outDir := os.Getenv("OUT_DIR")
-	if outDir == "" {
-		outDir = "out"
-	}
-
-	cujDir := filepath.Join(outDir, "cuj_tests")
-
-	wd, _ := os.Getwd()
-	os.Setenv("TOP", wd)
-	// Use a subdirectory for the out directory for the tests to keep them isolated.
-	os.Setenv("OUT_DIR", filepath.Join(cujDir, "out"))
-
-	// Each of these tests is run in sequence without resetting the output tree.  The state of the output tree will
-	// affect each successive test.  To maintain the validity of the benchmarks across changes, care must be taken
-	// to avoid changing the state of the tree when a test is run.  This is most easily accomplished by adding tests
-	// at the end.
-	tests := []Test{
-		{
-			// Reset the out directory to get reproducible results.
-			name: "clean",
-			args: []string{"clean"},
-		},
-		{
-			// Parse the build files.
-			name: "nothing",
-			args: []string{"nothing"},
-		},
-		{
-			// Parse the build files again to monitor issues like globs rerunning.
-			name: "nothing_rebuild",
-			args: []string{"nothing"},
-		},
-		{
-			// Parse the build files again, this should always be very short.
-			name: "nothing_rebuild_twice",
-			args: []string{"nothing"},
-		},
-		{
-			// Build the framework as a common developer task and one that keeps getting longer.
-			name: "framework",
-			args: []string{"framework"},
-		},
-		{
-			// Build the framework again to make sure it doesn't rebuild anything.
-			name: "framework_rebuild",
-			args: []string{"framework"},
-		},
-		{
-			// Build the framework again to make sure it doesn't rebuild anything even if it did the second time.
-			name: "framework_rebuild_twice",
-			args: []string{"framework"},
-		},
-		{
-			// Scenario major_inc_build (b/152046247): tracking build speed of major incremental build.
-			name: "major_inc_build_droid",
-			args: []string{"droid"},
-		},
-		{
-			name:   "major_inc_build_framework_minus_apex_after_droid_build",
-			args:   []string{"framework-minus-apex"},
-			before: touchIntentFile,
-		},
-		{
-			name:   "major_inc_build_framework_after_droid_build",
-			args:   []string{"framework"},
-			before: touchIntentFile,
-		},
-		{
-			name:   "major_inc_build_sync_after_droid_build",
-			args:   []string{"sync"},
-			before: touchIntentFile,
-		},
-		{
-			name:   "major_inc_build_droid_rebuild",
-			args:   []string{"droid"},
-			before: touchIntentFile,
-		},
-		{
-			name:   "major_inc_build_update_api_after_droid_rebuild",
-			args:   []string{"update-api"},
-			before: touchIntentFile,
-		},
-	}
-
-	cujMetrics := metrics.NewCriticalUserJourneysMetrics()
-	defer cujMetrics.Dump(filepath.Join(cujDir, "logs", "cuj_metrics.pb"))
-
-	for i, t := range tests {
-		logsSubDir := fmt.Sprintf("%02d_%s", i, t.name)
-		logsDir := filepath.Join(cujDir, "logs", logsSubDir)
-		if t.before != nil {
-			if err := t.before(); err != nil {
-				fmt.Printf("error running before function on test %q: %v\n", t.name, err)
-				break
-			}
-		}
-		t.Run(logsDir)
-		if t.results.err != nil {
-			fmt.Printf("error running test %q: %s\n", t.name, t.results.err)
-			break
-		}
-		if t.results.metrics != nil {
-			cujMetrics.Add(t.name, t.results.metrics)
-		}
-	}
-}
diff --git a/cuj/run_cuj_tests.sh b/cuj/run_cuj_tests.sh
deleted file mode 100755
index a746bd5..0000000
--- a/cuj/run_cuj_tests.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash -e
-
-readonly UNAME="$(uname)"
-case "$UNAME" in
-Linux)
-    readonly OS='linux'
-    ;;
-Darwin)
-    readonly OS='darwin'
-    ;;
-*)
-    echo "Unsupported OS '$UNAME'"
-    exit 1
-    ;;
-esac
-
-readonly ANDROID_TOP="$(cd $(dirname $0)/../../..; pwd)"
-cd "$ANDROID_TOP"
-
-export OUT_DIR="${OUT_DIR:-out}"
-
-build/soong/soong_ui.bash --make-mode "${OUT_DIR}/host/${OS}-x86/bin/cuj_tests"
-
-"${OUT_DIR}/host/${OS}-x86/bin/cuj_tests" || true
-
-if [ -n "${DIST_DIR}" ]; then
-  cp -r "${OUT_DIR}/cuj_tests/logs" "${DIST_DIR}"
-fi
diff --git a/docs/perf.md b/docs/perf.md
index 5b53c8d..446ba9d 100644
--- a/docs/perf.md
+++ b/docs/perf.md
@@ -61,8 +61,7 @@
 
 saves CPU profile for each Soong invocation in /tmp/foo._step_ file, where
 _step_ is Soong execution step. The main step is `build`. The others as
-`bp2build_files`, `bp2build_workspace`, `modulegraph`, `queryview`,
-`api_bp2build`, `soong_docs` (not all of them necessarily run during the build).
+`soong_docs` (not all of them necessarily run during the build).
 The profiles can be inspected with `go tool pprof` from the command line or
 with _Run>Open Profiler Snapshot_ in IntelliJ IDEA.
 
diff --git a/etc/otacerts_zip.go b/etc/otacerts_zip.go
index b6f175a..d12bdac 100644
--- a/etc/otacerts_zip.go
+++ b/etc/otacerts_zip.go
@@ -61,41 +61,41 @@
 
 var _ android.ImageInterface = (*otacertsZipModule)(nil)
 
-func (m *otacertsZipModule) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (m *otacertsZipModule) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
 
-func (m *otacertsZipModule) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (m *otacertsZipModule) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (m *otacertsZipModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return !m.ModuleBase.InstallInRecovery()
 }
 
-func (m *otacertsZipModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (m *otacertsZipModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (m *otacertsZipModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (m *otacertsZipModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(m.properties.Recovery_available) || m.ModuleBase.InstallInRecovery()
 }
 
-func (m *otacertsZipModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (m *otacertsZipModule) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
 	return nil
 }
 
-func (m *otacertsZipModule) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (m *otacertsZipModule) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
 }
 
 func (m *otacertsZipModule) InRecovery() bool {
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index fbe24d1..59712c0 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -236,30 +236,30 @@
 
 var _ android.ImageInterface = (*PrebuiltEtc)(nil)
 
-func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
 
-func (p *PrebuiltEtc) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (p *PrebuiltEtc) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() &&
 		!p.ModuleBase.InstallInVendorRamdisk() && !p.ModuleBase.InstallInDebugRamdisk()
 }
 
-func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk()
 }
 
-func (p *PrebuiltEtc) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(p.properties.Vendor_ramdisk_available) || p.ModuleBase.InstallInVendorRamdisk()
 }
 
-func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(p.properties.Debug_ramdisk_available) || p.ModuleBase.InstallInDebugRamdisk()
 }
 
@@ -267,15 +267,15 @@
 	return proptools.Bool(p.rootProperties.Install_in_root)
 }
 
-func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
 }
 
-func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (p *PrebuiltEtc) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
 	return nil
 }
 
-func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (p *PrebuiltEtc) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
 }
 
 func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index e796ab9..9d93925 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -75,7 +75,7 @@
 
 	// Path to the private key that avbtool will use to sign this filesystem image.
 	// TODO(jiyong): allow apex_key to be specified here
-	Avb_private_key *string `android:"path"`
+	Avb_private_key *string `android:"path_device_first"`
 
 	// Hash and signing algorithm for avbtool. Default is SHA256_RSA4096.
 	Avb_algorithm *string
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 9756b82..ca0a7f7 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -264,7 +264,10 @@
 func (f *filesystem) filterInstallablePackagingSpec(ps android.PackagingSpec) bool {
 	// Filesystem module respects the installation semantic. A PackagingSpec from a module with
 	// IsSkipInstall() is skipped.
-	return !ps.SkipInstall() && (ps.Partition() == f.PartitionType())
+	if proptools.Bool(f.properties.Is_auto_generated) { // TODO (spandandas): Remove this.
+		return !ps.SkipInstall() && (ps.Partition() == f.PartitionType())
+	}
+	return !ps.SkipInstall()
 }
 
 var pctx = android.NewPackageContext("android/soong/filesystem")
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 1e50836..7300061 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -588,6 +588,7 @@
 // If a system_ext/ module depends on system/ module, the dependency should *not*
 // be installed in system_ext/
 func TestDoNotPackageCrossPartitionDependencies(t *testing.T) {
+	t.Skip() // TODO (spandandas): Re-enable this
 	result := fixture.RunTestWithBp(t, `
 		android_filesystem {
 			name: "myfilesystem",
@@ -609,3 +610,57 @@
 	fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
 	android.AssertDeepEquals(t, "filesystem with dependencies on different partition", "bin/binfoo\n", fileList)
 }
+
+// If a cc_library is listed in `deps`, and it has a shared and static variant, then the shared variant
+// should be installed.
+func TestUseSharedVariationOfNativeLib(t *testing.T) {
+	result := fixture.RunTestWithBp(t, `
+		android_filesystem {
+			name: "myfilesystem",
+			deps: ["libfoo"],
+		}
+		// cc_library will create a static and shared variant.
+		cc_library {
+			name: "libfoo",
+		}
+	`)
+
+	partition := result.ModuleForTests("myfilesystem", "android_common")
+	fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
+	android.AssertDeepEquals(t, "cc_library listed in deps", "lib64/libc++.so\nlib64/libc.so\nlib64/libdl.so\nlib64/libfoo.so\nlib64/libm.so\n", fileList)
+}
+
+// binfoo1 overrides binbar. transitive deps of binbar should not be installed.
+func TestDoNotInstallTransitiveDepOfOverriddenModule(t *testing.T) {
+	result := fixture.RunTestWithBp(t, `
+android_filesystem {
+    name: "myfilesystem",
+    deps: ["binfoo1", "libfoo2", "binbar"],
+}
+cc_binary {
+    name: "binfoo1",
+    shared_libs: ["libfoo"],
+    overrides: ["binbar"],
+}
+cc_library {
+    name: "libfoo",
+}
+cc_library {
+    name: "libfoo2",
+    overrides: ["libfoo"],
+}
+// binbar gets overridden by binfoo1
+// therefore, libbar should not be installed
+cc_binary {
+    name: "binbar",
+    shared_libs: ["libbar"]
+}
+cc_library {
+    name: "libbar",
+}
+	`)
+
+	partition := result.ModuleForTests("myfilesystem", "android_common")
+	fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
+	android.AssertDeepEquals(t, "Shared library dep of overridden binary should not be installed", fileList, "bin/binfoo1\nlib64/libc++.so\nlib64/libc.so\nlib64/libdl.so\nlib64/libfoo2.so\nlib64/libm.so\n")
+}
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index 1d64796..51ba7c9 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -98,7 +98,7 @@
 func vbmetaFactory() android.Module {
 	module := &vbmeta{}
 	module.AddProperties(&module.properties)
-	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
 	return module
 }
 
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index dc7becb..c903338 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -101,6 +101,12 @@
 		if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
 			generatedPartitions = append(generatedPartitions, "system_ext")
 		}
+		if ctx.DeviceConfig().BuildingVendorImage() && ctx.DeviceConfig().VendorPath() == "vendor" {
+			generatedPartitions = append(generatedPartitions, "vendor")
+		}
+		if ctx.DeviceConfig().BuildingProductImage() && ctx.DeviceConfig().ProductPath() == "product" {
+			generatedPartitions = append(generatedPartitions, "product")
+		}
 
 		return &FsGenState{
 			depCandidates: candidates,
@@ -124,7 +130,10 @@
 					"public.libraries.android.txt": defaultDepCandidateProps(ctx.Config()),
 					"update_engine_sideload":       defaultDepCandidateProps(ctx.Config()),
 				},
-				"vendor":  newMultilibDeps(),
+				"vendor": &map[string]*depCandidateProps{
+					"fs_config_files_vendor": defaultDepCandidateProps(ctx.Config()),
+					"fs_config_dirs_vendor":  defaultDepCandidateProps(ctx.Config()),
+				},
 				"odm":     newMultilibDeps(),
 				"product": newMultilibDeps(),
 				"system_ext": &map[string]*depCandidateProps{
@@ -173,7 +182,7 @@
 	fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
 
 	m := mctx.Module()
-	if slices.Contains(fsGenState.depCandidates, m.Name()) {
+	if m.Target().Os.Class == android.Device && slices.Contains(fsGenState.depCandidates, m.Name()) {
 		installPartition := m.PartitionTag(mctx.DeviceConfig())
 		fsGenState.fsDepsMutex.Lock()
 		// Only add the module as dependency when:
@@ -210,14 +219,6 @@
 	return fmt.Sprintf("//%s:%s", namespace, moduleName)
 }
 
-// Returns the sorted unique list of module names with namespace, if the module specifies one.
-func fullyQualifiedModuleNames(modules multilibDeps) (ret []string) {
-	for moduleName, moduleProp := range *modules {
-		ret = append(ret, fullyQualifiedModuleName(moduleName, moduleProp.Namespace))
-	}
-	return android.SortedUniqueStrings(ret)
-}
-
 func getBitness(archTypes []android.ArchType) (ret []string) {
 	for _, archType := range archTypes {
 		if archType.Multilib == "" {
@@ -274,6 +275,13 @@
 			depsStruct.Multilib.Common.Deps = append(depsStruct.Multilib.Common.Deps, fullyQualifiedDepName)
 		}
 	}
+	depsStruct.Deps = android.SortedUniqueStrings(depsStruct.Deps)
+	depsStruct.Multilib.Lib32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib32.Deps)
+	depsStruct.Multilib.Lib64.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib64.Deps)
+	depsStruct.Multilib.Prefer32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Prefer32.Deps)
+	depsStruct.Multilib.Both.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Both.Deps)
+	depsStruct.Multilib.Common.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Common.Deps)
+
 	return &depsStruct
 }
 
@@ -341,6 +349,12 @@
 	if android.InList("system_ext", f.properties.Generated_partition_types) {
 		partitionProps.System_ext_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
 	}
+	if android.InList("vendor", f.properties.Generated_partition_types) {
+		partitionProps.Vendor_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
+	}
+	if android.InList("product", f.properties.Generated_partition_types) {
+		partitionProps.Product_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
+	}
 
 	ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps)
 }
@@ -351,6 +365,24 @@
 		fsProps.Build_logtags = proptools.BoolPtr(true)
 		// https://source.corp.google.com/h/googleplex-android/platform/build//639d79f5012a6542ab1f733b0697db45761ab0f3:core/packaging/flags.mk;l=21;drc=5ba8a8b77507f93aa48cc61c5ba3f31a4d0cbf37;bpv=1;bpt=0
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
+		// Identical to that of the generic_system_image
+		fsProps.Fsverity.Inputs = []string{
+			"etc/boot-image.prof",
+			"etc/dirty-image-objects",
+			"etc/preloaded-classes",
+			"etc/classpaths/*.pb",
+			"framework/*",
+			"framework/*/*",     // framework/{arch}
+			"framework/oat/*/*", // framework/oat/{arch}
+		}
+		fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
+	case "system_ext":
+		fsProps.Fsverity.Inputs = []string{
+			"framework/*",
+			"framework/*/*",     // framework/{arch}
+			"framework/oat/*/*", // framework/oat/{arch}
+		}
+		fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
 	case "product":
 		fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
 	case "vendor":
@@ -430,18 +462,6 @@
 
 	fsProps.Is_auto_generated = proptools.BoolPtr(true)
 
-	// Identical to that of the generic_system_image
-	fsProps.Fsverity.Inputs = []string{
-		"etc/boot-image.prof",
-		"etc/dirty-image-objects",
-		"etc/preloaded-classes",
-		"etc/classpaths/*.pb",
-		"framework/*",
-		"framework/*/*",     // framework/{arch}
-		"framework/oat/*/*", // framework/oat/{arch}
-	}
-	fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
-
 	partitionSpecificFsProps(fsProps, partitionType)
 
 	// system_image properties that are not set:
@@ -514,9 +534,14 @@
 	}
 	f.HideFromMake()
 
-	content := generateBpContent(ctx, "system")
-	generatedBp := android.PathForOutput(ctx, "soong_generated_product_config.bp")
-	android.WriteFileRule(ctx, generatedBp, content)
+	var content strings.Builder
+	generatedBp := android.PathForModuleOut(ctx, "soong_generated_product_config.bp")
+	for _, partition := range ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions {
+		content.WriteString(generateBpContent(ctx, partition))
+		content.WriteString("\n")
+	}
+	android.WriteFileRule(ctx, generatedBp, content.String())
+
 	ctx.Phony("product_config_to_bp", generatedBp)
 
 	var diffTestFiles []android.Path
@@ -534,10 +559,6 @@
 }
 
 func generateBpContent(ctx android.EarlyModuleContext, partitionType string) string {
-	// Currently only system partition is supported
-	if partitionType != "system" {
-		return ""
-	}
 	fsProps, fsTypeSupported := generateFsProps(ctx, partitionType)
 	if !fsTypeSupported {
 		return ""
@@ -552,10 +573,15 @@
 		ctx.ModuleErrorf(err.Error())
 	}
 
+	moduleType := "android_filesystem"
+	if partitionType == "system" {
+		moduleType = "android_system_image"
+	}
+
 	file := &parser.File{
 		Defs: []parser.Definition{
 			&parser.Module{
-				Type: "module",
+				Type: moduleType,
 				Map:  *result,
 			},
 		},
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index 42fd228..aa393a2 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -411,6 +411,11 @@
 	// Optional list of seed files to be installed to the fuzz target's output
 	// directory.
 	Corpus []string `android:"path"`
+
+	// Same as corpus, but adds dependencies on module references using the device's os variant
+	// and the common arch variant.
+	Device_common_corpus []string `android:"path_device_common"`
+
 	// Optional list of data files to be installed to the fuzz target's output
 	// directory. Directory structure relative to the module is preserved.
 	Data []string `android:"path"`
diff --git a/genrule/genrule.go b/genrule/genrule.go
index f2a761c..1ab1378 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -147,6 +147,18 @@
 	// list of input files
 	Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
 
+	// Same as srcs, but will add dependencies on modules via a device os variation and the device's
+	// first supported arch's variation. Can be used to add a dependency from a host genrule to
+	// a device module.
+	Device_first_srcs proptools.Configurable[[]string] `android:"path_device_first"`
+
+	// Same as srcs, but will add dependencies on modules via a device os variation and the common
+	// arch variation. Can be used to add a dependency from a host genrule to a device module.
+	Device_common_srcs proptools.Configurable[[]string] `android:"path_device_common"`
+
+	// Same as srcs, but will add dependencies on modules via a common_os os variation.
+	Common_os_srcs proptools.Configurable[[]string] `android:"path_common_os"`
+
 	// input files to exclude
 	Exclude_srcs []string `android:"path,arch_variant"`
 
@@ -289,7 +301,15 @@
 // approach zero; there should be no genrule action registration done directly
 // by Soong logic in the mixed-build case.
 func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) {
-	g.subName = ctx.ModuleSubDir()
+	// Add the variant as a suffix to the make modules to create, so that the make modules
+	// don't conflict because make doesn't know about variants. However, this causes issues with
+	// tracking required dependencies as the required property in soong is passed straight to make
+	// without accounting for these suffixes. To make it a little easier to work with, don't use
+	// a suffix for android_common variants so that java_genrules look like regular 1-variant
+	// genrules to make.
+	if ctx.ModuleSubDir() != "android_common" {
+		g.subName = ctx.ModuleSubDir()
+	}
 
 	if len(g.properties.Export_include_dirs) > 0 {
 		for _, dir := range g.properties.Export_include_dirs {
@@ -431,6 +451,9 @@
 	}
 	srcs := g.properties.Srcs.GetOrDefault(ctx, nil)
 	srcFiles := addLabelsForInputs("srcs", srcs, g.properties.Exclude_srcs)
+	srcFiles = append(srcFiles, addLabelsForInputs("device_first_srcs", g.properties.Device_first_srcs.GetOrDefault(ctx, nil), nil)...)
+	srcFiles = append(srcFiles, addLabelsForInputs("device_common_srcs", g.properties.Device_common_srcs.GetOrDefault(ctx, nil), nil)...)
+	srcFiles = append(srcFiles, addLabelsForInputs("common_os_srcs", g.properties.Common_os_srcs.GetOrDefault(ctx, nil), nil)...)
 	android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()})
 
 	var copyFrom android.Paths
@@ -723,16 +746,22 @@
 
 type noopImageInterface struct{}
 
-func (x noopImageInterface) ImageMutatorBegin(android.BaseModuleContext)                 {}
-func (x noopImageInterface) VendorVariantNeeded(android.BaseModuleContext) bool          { return false }
-func (x noopImageInterface) ProductVariantNeeded(android.BaseModuleContext) bool         { return false }
-func (x noopImageInterface) CoreVariantNeeded(android.BaseModuleContext) bool            { return false }
-func (x noopImageInterface) RamdiskVariantNeeded(android.BaseModuleContext) bool         { return false }
-func (x noopImageInterface) VendorRamdiskVariantNeeded(android.BaseModuleContext) bool   { return false }
-func (x noopImageInterface) DebugRamdiskVariantNeeded(android.BaseModuleContext) bool    { return false }
-func (x noopImageInterface) RecoveryVariantNeeded(android.BaseModuleContext) bool        { return false }
-func (x noopImageInterface) ExtraImageVariations(ctx android.BaseModuleContext) []string { return nil }
-func (x noopImageInterface) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (x noopImageInterface) ImageMutatorBegin(android.ImageInterfaceContext)         {}
+func (x noopImageInterface) VendorVariantNeeded(android.ImageInterfaceContext) bool  { return false }
+func (x noopImageInterface) ProductVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) CoreVariantNeeded(android.ImageInterfaceContext) bool    { return false }
+func (x noopImageInterface) RamdiskVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) VendorRamdiskVariantNeeded(android.ImageInterfaceContext) bool {
+	return false
+}
+func (x noopImageInterface) DebugRamdiskVariantNeeded(android.ImageInterfaceContext) bool {
+	return false
+}
+func (x noopImageInterface) RecoveryVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
+	return nil
+}
+func (x noopImageInterface) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
 }
 
 func NewGenSrcs() *Module {
diff --git a/java/aapt2.go b/java/aapt2.go
index 61cf373..bae4d1e 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -15,7 +15,9 @@
 package java
 
 import (
+	"fmt"
 	"path/filepath"
+	"regexp"
 	"sort"
 	"strconv"
 	"strings"
@@ -31,19 +33,35 @@
 	return strings.HasPrefix(lastDir, "values")
 }
 
+func isFlagsPath(subDir string) bool {
+	re := regexp.MustCompile(`flag\(!?([a-zA-Z_-]+\.)*[a-zA-Z0-9_-]+\)`)
+	lastDir := filepath.Base(subDir)
+	return re.MatchString(lastDir)
+}
+
 // Convert input resource file path to output file path.
 // values-[config]/<file>.xml -> values-[config]_<file>.arsc.flat;
+// flag(fully.qualified.flag_name)/values-[config]/<file>.xml -> /values-[config]_<file>.(fully.qualified.flag_name).arsc.flat;
 // For other resource file, just replace the last "/" with "_" and add .flat extension.
 func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.WritablePath {
 
-	name := res.Base()
+	extension := filepath.Ext(res.Base())
+	name := strings.TrimSuffix(res.Base(), extension)
 	if isPathValueResource(res) {
-		name = strings.TrimSuffix(name, ".xml") + ".arsc"
+		extension = ".arsc"
 	}
 	subDir := filepath.Dir(res.String())
 	subDir, lastDir := filepath.Split(subDir)
-	name = lastDir + "_" + name + ".flat"
-	return android.PathForModuleOut(ctx, "aapt2", subDir, name)
+	if isFlagsPath(subDir) {
+		var flag string
+		subDir, flag = filepath.Split(filepath.Dir(subDir))
+		flag = strings.TrimPrefix(flag, "flag")
+		name = fmt.Sprintf("%s_%s.%s%s.flat", lastDir, name, flag, extension)
+	} else {
+		name = fmt.Sprintf("%s_%s%s.flat", lastDir, name, extension)
+	}
+	out := android.PathForModuleOut(ctx, "aapt2", subDir, name)
+	return out
 }
 
 // pathsToAapt2Paths Calls pathToAapt2Path on each entry of the given Paths, i.e. []Path.
diff --git a/java/app.go b/java/app.go
index 69fdc47..56fcfbb 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1340,12 +1340,14 @@
 			Aaptflags      []string
 			Manifest       *string
 			Resource_dirs  []string
+			Flags_packages []string
 		}{
 			Name:           proptools.StringPtr(rroPackageName),
 			Filter_product: proptools.StringPtr(characteristics),
 			Aaptflags:      []string{"--auto-add-overlay"},
 			Manifest:       proptools.StringPtr(":" + rroManifestName),
 			Resource_dirs:  a.aaptProperties.Resource_dirs,
+			Flags_packages: a.aaptProperties.Flags_packages,
 		}
 		if !Bool(a.aaptProperties.Aapt_include_all_resources) {
 			for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
@@ -1438,6 +1440,8 @@
 	a.testConfig = a.FixTestConfig(ctx, testConfig)
 	a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
 	a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
+	a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
+	a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
 	android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
 	android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
 		InstalledFiles:          a.data,
diff --git a/java/app_test.go b/java/app_test.go
index dd672a0..3d83ea1 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -4679,3 +4679,51 @@
 		"--override-placeholder-version",
 	)
 }
+
+func TestResourcesWithFlagDirectories(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		PrepareForTestWithJavaDefaultModules,
+		android.FixtureMergeMockFs(android.MockFS{
+			"res/flag(test.package.flag1)/values/bools.xml":                          nil,
+			"res/flag(!test.package.flag2)/values/bools.xml":                         nil,
+			"res/flag(test.package.flag1)/values-config/strings_google_services.xml": nil,
+			"res/flags(test.package.flag1)/values/strings.xml":                       nil,
+		}),
+	).RunTestWithBp(t, `
+		android_library {
+			name: "foo",
+			srcs: ["a.java"],
+			use_resource_processor: true,
+			resource_dirs: [
+				"res",
+			],
+		}
+	`)
+	fooModule := result.ModuleForTests("foo", "android_common")
+	compileOutputPaths := fooModule.Rule("aapt2Compile").Outputs.Strings()
+
+	android.AssertStringListContains(
+		t,
+		"Expected to generate flag path",
+		compileOutputPaths,
+		"out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(test.package.flag1).arsc.flat",
+	)
+	android.AssertStringListContains(
+		t,
+		"Expected to generate flag path with ! prefix in name",
+		compileOutputPaths,
+		"out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(!test.package.flag2).arsc.flat",
+	)
+	android.AssertStringListContains(
+		t,
+		"Expected to generate flag path with configs",
+		compileOutputPaths,
+		"out/soong/.intermediates/foo/android_common/aapt2/res/values-config_strings_google_services.(test.package.flag1).arsc.flat",
+	)
+	android.AssertStringListDoesNotContain(
+		t,
+		"Expected to not generate flag path with non-flag(flag_name) pattern",
+		compileOutputPaths,
+		"out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat",
+	)
+}
diff --git a/java/base.go b/java/base.go
index f075dbd..3927c61 100644
--- a/java/base.go
+++ b/java/base.go
@@ -71,6 +71,15 @@
 	// list of files that should be excluded from java_resources and java_resource_dirs
 	Exclude_java_resources []string `android:"path,arch_variant"`
 
+	// Same as java_resources, but modules added here will use the device variant. Can be useful
+	// for making a host test that tests the contents of a device built app.
+	Device_common_java_resources []string `android:"path_device_common"`
+
+	// Same as java_resources, but modules added here will use the device's os variant and the
+	// device's first architecture variant. Can be useful for making a host test that tests the
+	// contents of a native device built app.
+	Device_first_java_resources []string `android:"path_device_first"`
+
 	// list of module-specific flags that will be used for javac compiles
 	Javacflags []string `android:"arch_variant"`
 
@@ -1486,6 +1495,10 @@
 	dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
 		j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
 	fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
+	fileArgs2, fileDeps2 := ResourceFilesToJarArgs(ctx, j.properties.Device_common_java_resources, nil)
+	fileArgs3, fileDeps3 := ResourceFilesToJarArgs(ctx, j.properties.Device_first_java_resources, nil)
+	fileArgs = slices.Concat(fileArgs, fileArgs2, fileArgs3)
+	fileDeps = slices.Concat(fileDeps, fileDeps2, fileDeps3)
 	extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources
 
 	var resArgs []string
diff --git a/java/dex.go b/java/dex.go
index a3f699b..f4b53f0 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -404,6 +404,10 @@
 		r8Flags = append(r8Flags, "--resource-output", d.resourcesOutput.Path().String())
 		if d.dexProperties.optimizedResourceShrinkingEnabled(ctx) {
 			r8Flags = append(r8Flags, "--optimized-resource-shrinking")
+			if Bool(d.dexProperties.Optimize.Optimized_shrink_resources) {
+				// Explicitly opted into optimized shrinking, no need for keeping R$id entries
+				r8Flags = append(r8Flags, "--force-optimized-resource-shrinking")
+			}
 		}
 	}
 
diff --git a/java/fuzz.go b/java/fuzz.go
index e5f1f04..90f09a8 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -110,6 +110,9 @@
 	if j.fuzzPackagedModule.FuzzProperties.Corpus != nil {
 		j.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Corpus)
 	}
+	if j.fuzzPackagedModule.FuzzProperties.Device_common_corpus != nil {
+		j.fuzzPackagedModule.Corpus = append(j.fuzzPackagedModule.Corpus, android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Device_common_corpus)...)
+	}
 	if j.fuzzPackagedModule.FuzzProperties.Data != nil {
 		j.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Data)
 	}
diff --git a/java/java.go b/java/java.go
index 8b30262..5bb3636 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1291,6 +1291,16 @@
 	// the test
 	Data []string `android:"path"`
 
+	// Same as data, but will add dependencies on modules using the device's os variation and
+	// the common arch variation. Useful for a host test that wants to embed a module built for
+	// device.
+	Device_common_data []string `android:"path_device_common"`
+
+	// same as data, but adds dependencies using the device's os variation and the device's first
+	// architecture's variation. Can be used to add a module built for device to the data of a
+	// host test.
+	Device_first_data []string `android:"path_device_first"`
+
 	// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
 	// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
 	// explicitly.
@@ -1581,6 +1591,8 @@
 	})
 
 	j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
+	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_common_data)...)
+	j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_data)...)
 
 	j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
 
diff --git a/java/java_resources.go b/java/java_resources.go
index b0dc5a1..c525233 100644
--- a/java/java_resources.go
+++ b/java/java_resources.go
@@ -17,6 +17,7 @@
 import (
 	"fmt"
 	"path/filepath"
+	"slices"
 	"strings"
 
 	"github.com/google/blueprint/pathtools"
@@ -99,10 +100,7 @@
 // that should not be treated as resources (including *.java).
 func ResourceFilesToJarArgs(ctx android.ModuleContext,
 	res, exclude []string) (args []string, deps android.Paths) {
-
-	exclude = append([]string(nil), exclude...)
-	exclude = append(exclude, resourceExcludes...)
-	return resourceFilesToJarArgs(ctx, res, exclude)
+	return resourceFilesToJarArgs(ctx, res, slices.Concat(exclude, resourceExcludes))
 }
 
 func resourceFilesToJarArgs(ctx android.ModuleContext,
diff --git a/java/java_test.go b/java/java_test.go
index 51cfdab..54eb3e1 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1173,7 +1173,7 @@
 
 				filegroup {
 					name: "core-jar",
-					srcs: [":core{.jar}"],
+					device_common_srcs: [":core{.jar}"],
 				}
 		`),
 	})
@@ -1189,7 +1189,7 @@
 
 				filegroup {
 					name: "core-jar",
-					srcs: [":core{.jar}"],
+					device_common_srcs: [":core{.jar}"],
 				}
 		`),
 	})
diff --git a/java/robolectric.go b/java/robolectric.go
index 30c7203..fb820ef 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -149,6 +149,8 @@
 		HostTemplate:           "${RobolectricTestConfigTemplate}",
 	})
 	r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
+	r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_common_data)...)
+	r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_data)...)
 
 	var ok bool
 	var instrumentedApp *AndroidApp
@@ -208,6 +210,11 @@
 	installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
 	var installDeps android.InstallPaths
 
+	for _, data := range r.data {
+		installedData := ctx.InstallFile(installPath, data.Rel(), data)
+		installDeps = append(installDeps, installedData)
+	}
+
 	if manifest != nil {
 		r.data = append(r.data, manifest)
 		installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", manifest)
@@ -228,11 +235,6 @@
 	installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
 	installDeps = append(installDeps, installedConfig)
 
-	for _, data := range android.PathsForModuleSrc(ctx, r.testProperties.Data) {
-		installedData := ctx.InstallFile(installPath, data.Rel(), data)
-		installDeps = append(installDeps, installedData)
-	}
-
 	soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
 	for _, jniLib := range collectTransitiveJniDeps(ctx) {
 		installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
diff --git a/python/python.go b/python/python.go
index 01ac86c..d3e5743 100644
--- a/python/python.go
+++ b/python/python.go
@@ -90,6 +90,11 @@
 	// the test. the file extension can be arbitrary except for (.py).
 	Data []string `android:"path,arch_variant"`
 
+	// Same as data, but will add dependencies on modules using the device's os variation and
+	// the common arch variation. Useful for a host test that wants to embed a module built for
+	// device.
+	Device_common_data []string `android:"path_device_common"`
+
 	// list of java modules that provide data that should be installed alongside the test.
 	Java_data []string
 
@@ -451,6 +456,7 @@
 
 	// expand data files from "data" property.
 	expandedData := android.PathsForModuleSrc(ctx, p.properties.Data)
+	expandedData = append(expandedData, android.PathsForModuleSrc(ctx, p.properties.Device_common_data)...)
 
 	// Emulate the data property for java_data dependencies.
 	for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
diff --git a/python/test.go b/python/test.go
index 85decf9..acf5b26 100644
--- a/python/test.go
+++ b/python/test.go
@@ -65,6 +65,11 @@
 	// the test
 	Data []string `android:"path,arch_variant"`
 
+	// Same as data, but will add dependencies on modules using the device's os variation and
+	// the common arch variation. Useful for a host test that wants to embed a module built for
+	// device.
+	Device_common_data []string `android:"path_device_common"`
+
 	// list of java modules that provide data that should be installed alongside the test.
 	Java_data []string
 
@@ -183,6 +188,9 @@
 	for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Data) {
 		p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath})
 	}
+	for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Device_common_data) {
+		p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath})
+	}
 
 	if p.isTestHost() && len(p.testProperties.Data_device_bins_both) > 0 {
 		ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
diff --git a/rust/bindgen.go b/rust/bindgen.go
index abb5181..3944495 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -186,7 +186,7 @@
 	// Default clang flags
 	cflags = append(cflags, "${cc_config.CommonGlobalCflags}")
 	if ctx.Device() {
-		cflags = append(cflags, "${cc_config.DeviceGlobalCflags}")
+		cflags = append(cflags, "${cc_config.DeviceGlobalCflags}", "-nostdlibinc")
 	}
 
 	// Toolchain clang flags
diff --git a/rust/image.go b/rust/image.go
index 26929b1..51b8289 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -85,7 +85,7 @@
 	mod.Properties.VendorVariantNeeded = b
 }
 
-func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
+func (mod *Module) SnapshotVersion(mctx android.ImageInterfaceContext) string {
 	if snapshot, ok := mod.compiler.(cc.SnapshotInterface); ok {
 		return snapshot.Version()
 	} else {
@@ -94,35 +94,35 @@
 	}
 }
 
-func (mod *Module) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return mod.Properties.VendorVariantNeeded
 }
 
-func (mod *Module) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return mod.Properties.ProductVariantNeeded
 }
 
-func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return mod.Properties.VendorRamdiskVariantNeeded
 }
 
-func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return mod.Properties.CoreVariantNeeded
 }
 
-func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool {
+func (mod *Module) RamdiskVariantNeeded(android.ImageInterfaceContext) bool {
 	return mod.Properties.RamdiskVariantNeeded
 }
 
-func (mod *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool {
+func (mod *Module) RecoveryVariantNeeded(android.ImageInterfaceContext) bool {
 	return mod.Properties.RecoveryVariantNeeded
 }
 
-func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string {
+func (mod *Module) ExtraImageVariations(android.ImageInterfaceContext) []string {
 	return mod.Properties.ExtraVariants
 }
 
@@ -213,7 +213,7 @@
 	return mod.InVendor() || mod.InProduct()
 }
 
-func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant string) {
+func (mod *Module) SetImageVariation(ctx android.ImageInterfaceContext, variant string) {
 	if variant == android.VendorRamdiskVariation {
 		mod.MakeAsPlatform()
 	} else if variant == android.RecoveryVariation {
@@ -231,7 +231,7 @@
 	}
 }
 
-func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
+func (mod *Module) ImageMutatorBegin(mctx android.ImageInterfaceContext) {
 	if Bool(mod.VendorProperties.Double_loadable) {
 		mctx.PropertyErrorf("double_loadable",
 			"Rust modules do not yet support double loading")
diff --git a/rust/test.go b/rust/test.go
index b7ddd06..20ccfb3 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -46,6 +46,9 @@
 	// the test
 	Data []string `android:"path,arch_variant"`
 
+	// Same as data, but will add dependencies on the device's
+	Device_common_data []string `android:"path_device_common"`
+
 	// list of shared library modules that should be installed alongside the test
 	Data_libs []string `android:"arch_variant"`
 
@@ -143,6 +146,7 @@
 	})
 
 	dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
+	dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...)
 
 	ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
diff --git a/scripts/diff_build_graphs.sh b/scripts/diff_build_graphs.sh
deleted file mode 100755
index 8d01124..0000000
--- a/scripts/diff_build_graphs.sh
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/bin/bash -eu
-#
-# Copyright 2017 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-set -e
-
-# This file makes it easy to confirm that a set of changes in source code don't result in any
-# changes to the generated ninja files. This is to reduce the effort required to be confident
-# in the correctness of refactorings
-
-function die() {
-  echo "$@" >&2
-  exit 1
-}
-
-function usage() {
-  violation="$1"
-  die "$violation
-
-  Usage: diff_build_graphs.sh [--products=product1,product2...] <OLD_VERSIONS> <NEW_VERSIONS>
-
-  This file builds and parses the build files (Android.mk, Android.bp, etc) for each requested
-  product and for both sets of versions, and checks whether the ninja files (which implement
-  the build graph) changed between the two versions.
-
-  Example: diff_build_graphs.sh 'build/soong:work^ build/blueprint:work^' 'build/soong:work build/blueprint:work'
-
-  Options:
-    --products=PRODUCTS  comma-separated list of products to check"
-}
-
-PRODUCTS_ARG=""
-OLD_VERSIONS=""
-NEW_VERSIONS=""
-function parse_args() {
-  # parse optional arguments
-  while true; do
-    arg="${1-}"
-    case "$arg" in
-      --products=*) PRODUCTS_ARG="$arg";;
-      *) break;;
-    esac
-    shift
-  done
-  # parse required arguments
-  if [ "$#" != "2" ]; then
-    usage ""
-  fi
-  #argument validation
-  OLD_VERSIONS="$1"
-  NEW_VERSIONS="$2"
-
-}
-parse_args "$@"
-
-
-# find some file paths
-cd "$(dirname $0)"
-SCRIPT_DIR="$PWD"
-cd ../../..
-CHECKOUT_ROOT="$PWD"
-OUT_DIR="${OUT_DIR-}"
-if [ -z "$OUT_DIR" ]; then
-  OUT_DIR=out
-fi
-WORK_DIR="$OUT_DIR/diff"
-OUT_DIR_OLD="$WORK_DIR/out_old"
-OUT_DIR_NEW="$WORK_DIR/out_new"
-OUT_DIR_TEMP="$WORK_DIR/out_temp"
-
-
-function checkout() {
-  versionSpecs="$1"
-  for versionSpec in $versionSpecs; do
-    project="$(echo $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\1|')"
-    ref="$(echo     $versionSpec | sed 's|\([^:]*\):\([^:]*\)|\2|')"
-    echo "checking out ref $ref in project $project"
-    git -C "$project" checkout "$ref"
-  done
-}
-
-function run_build() {
-  echo
-  echo "Starting build"
-  # rebuild multiproduct_kati, in case it was missing before,
-  # or in case it is affected by some of the changes we're testing
-  make blueprint_tools
-  # find multiproduct_kati and have it build the ninja files for each product
-  builder="$(echo $OUT_DIR/host/*/bin/multiproduct_kati)"
-  BUILD_NUMBER=sample "$builder" $PRODUCTS_ARG --keep --out "$OUT_DIR_TEMP" || true
-  echo
-}
-
-function diffProduct() {
-  product="$1"
-
-  zip1="$OUT_DIR_OLD/${product}.zip"
-  unzipped1="$OUT_DIR_OLD/$product"
-
-  zip2="$OUT_DIR_NEW/${product}.zip"
-  unzipped2="$OUT_DIR_NEW/$product"
-
-  unzip -qq "$zip1" -d "$unzipped1"
-  unzip -qq "$zip2" -d "$unzipped2"
-
-  #do a diff of the ninja files
-  diffFile="$WORK_DIR/diff.txt"
-  diff -r "$unzipped1" "$unzipped2" -x build_date.txt -x build_number.txt -x '\.*' -x '*.log' -x build_fingerprint.txt -x build.ninja.d -x '*.zip' > $diffFile || true
-  if [[ -s "$diffFile" ]]; then
-    # outputs are different, so remove the unzipped versions but keep the zipped versions
-    echo "First few differences (total diff linecount=$(wc -l $diffFile)) for product $product:"
-    cat "$diffFile" | head -n 10
-    echo "End of differences for product $product"
-    rm -rf "$unzipped1" "$unzipped2"
-  else
-    # outputs are the same, so remove all of the outputs
-    rm -rf "$zip1" "$unzipped1" "$zip2" "$unzipped2"
-  fi
-}
-
-function do_builds() {
-  #reset work dir
-  rm -rf "$WORK_DIR"
-  mkdir "$WORK_DIR"
-
-  #build new code
-  checkout "$NEW_VERSIONS"
-  run_build
-  mv "$OUT_DIR_TEMP" "$OUT_DIR_NEW"
-
-  #build old code
-  #TODO do we want to cache old results? Maybe by the time we care to cache old results this will
-  #be running on a remote server somewhere and be completely different
-  checkout "$OLD_VERSIONS"
-  run_build
-  mv "$OUT_DIR_TEMP" "$OUT_DIR_OLD"
-
-  #cleanup
-  echo created "$OUT_DIR_OLD" and "$OUT_DIR_NEW"
-}
-
-function main() {
-  do_builds
-  checkout "$NEW_VERSIONS"
-
-  #find all products
-  productsFile="$WORK_DIR/all_products.txt"
-  find $OUT_DIR_OLD $OUT_DIR_NEW -mindepth 1 -maxdepth 1 -name "*.zip" | sed "s|^$OUT_DIR_OLD/||" | sed "s|^$OUT_DIR_NEW/||" | sed "s|\.zip$||" | sort | uniq > "$productsFile"
-  echo Diffing products
-  for product in $(cat $productsFile); do
-    diffProduct "$product"
-  done
-  echo Done diffing products
-  echo "Any differing outputs can be seen at $OUT_DIR_OLD/*.zip and $OUT_DIR_NEW/*.zip"
-  echo "See $WORK_DIR/diff.txt for the full list of differences for the latest product checked"
-}
-
-main
diff --git a/scripts/hiddenapi/Android.bp b/scripts/hiddenapi/Android.bp
index 43edf44..061af19 100644
--- a/scripts/hiddenapi/Android.bp
+++ b/scripts/hiddenapi/Android.bp
@@ -27,6 +27,12 @@
     libs: [
         "signature_trie",
     ],
+    target: {
+        windows: {
+            // go modules (bpmodify) don't support windows
+            enabled: false,
+        },
+    },
 }
 
 python_test_host {
@@ -44,6 +50,12 @@
     test_options: {
         unit_test: true,
     },
+    target: {
+        windows: {
+            // go modules (bpmodify) don't support windows
+            enabled: false,
+        },
+    },
 }
 
 python_binary_host {
diff --git a/sdk/genrule_test.go b/sdk/genrule_test.go
index 6e52a3d..bf67795 100644
--- a/sdk/genrule_test.go
+++ b/sdk/genrule_test.go
@@ -23,21 +23,14 @@
 )
 
 func TestSdkGenrule(t *testing.T) {
-	// Test that an sdk_genrule can depend on an sdk, and that a genrule can depend on an sdk_genrule
+	// Test that a genrule can depend on an sdk if using common_os_srcs
 	bp := `
 				sdk {
 					name: "my_sdk",
 				}
-				sdk_genrule {
-					name: "my_sdk_genrule",
-					tool_files: ["tool"],
-					cmd: "$(location tool) $(in) $(out)",
-					srcs: [":my_sdk"],
-					out: ["out"],
-				}
 				genrule {
 					name: "my_regular_genrule",
-					srcs: [":my_sdk_genrule"],
+					common_os_srcs: [":my_sdk"],
 					out: ["out"],
 					cmd: "cp $(in) $(out)",
 				}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 15e13db..4db163c 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -1724,7 +1724,7 @@
 
 		filegroup {
 			name: "mygroup",
-			srcs: [":myjavalib{.doctags}"],
+			device_common_srcs: [":myjavalib{.doctags}"],
 		}
 	`)
 
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 2e48d83..3991449 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -120,6 +120,16 @@
 	// the test.
 	Data []string `android:"path,arch_variant"`
 
+	// same as data, but adds dependencies using the device's os variation and the common
+	// architecture's variation. Can be used to add a module built for device to the data of a
+	// host test.
+	Device_common_data []string `android:"path_device_common"`
+
+	// same as data, but adds dependencies using the device's os variation and the device's first
+	// architecture's variation. Can be used to add a module built for device to the data of a
+	// host test.
+	Device_first_data []string `android:"path_device_first"`
+
 	// Add RootTargetPreparer to auto generated test config. This guarantees the test to run
 	// with root permission.
 	Require_root *bool
@@ -210,41 +220,41 @@
 
 var _ android.ImageInterface = (*ShBinary)(nil)
 
-func (s *ShBinary) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (s *ShBinary) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
 
-func (s *ShBinary) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return s.InstallInVendor()
 }
 
-func (s *ShBinary) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return s.InstallInProduct()
 }
 
-func (s *ShBinary) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return !s.InstallInRecovery() && !s.InstallInRamdisk() && !s.InstallInVendorRamdisk() && !s.ModuleBase.InstallInVendor()
 }
 
-func (s *ShBinary) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(s.properties.Ramdisk_available) || s.InstallInRamdisk()
 }
 
-func (s *ShBinary) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(s.properties.Vendor_ramdisk_available) || s.InstallInVendorRamdisk()
 }
 
-func (s *ShBinary) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return false
 }
 
-func (s *ShBinary) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
 	return proptools.Bool(s.properties.Recovery_available) || s.InstallInRecovery()
 }
 
-func (s *ShBinary) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (s *ShBinary) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
 	return nil
 }
 
-func (s *ShBinary) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (s *ShBinary) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
 	s.properties.ImageVariation = variation
 }
 
@@ -407,6 +417,8 @@
 	s.ShBinary.generateAndroidBuildActions(ctx)
 
 	expandedData := android.PathsForModuleSrc(ctx, s.testProperties.Data)
+	expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_common_data)...)
+	expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_first_data)...)
 	// Emulate the data property for java_data dependencies.
 	for _, javaData := range ctx.GetDirectDepsWithTag(shTestJavaDataTag) {
 		expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...)
diff --git a/shared/paths.go b/shared/paths.go
index 1ee66d5..64f94ba 100644
--- a/shared/paths.go
+++ b/shared/paths.go
@@ -20,14 +20,6 @@
 	"path/filepath"
 )
 
-// A SharedPaths represents a list of paths that are shared between
-// soong_ui and soong.
-type SharedPaths interface {
-	// BazelMetricsDir returns the path where a set of bazel profile
-	// files are stored for later processed by the metrics pipeline.
-	BazelMetricsDir() string
-}
-
 // Joins the path strings in the argument list, taking absolute paths into
 // account. That is, if one of the strings is an absolute path, the ones before
 // are ignored.
diff --git a/tests/b_args_test.sh b/tests/b_args_test.sh
deleted file mode 100755
index 0dfbabf..0000000
--- a/tests/b_args_test.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash -eu
-
-# This file tests the creation of bazel commands for b usage
-set -o pipefail
-source "$(dirname "$0")/../../bazel/lib.sh"
-
-BES_UUID="blank"
-OUT_DIR="arbitrary_out"
-b_args=$(formulate_b_args "build --config=nonsense foo:bar")
-
-if [[ $b_args != "build --profile=$OUT_DIR/bazel_metrics-profile --config=bp2build --invocation_id=$BES_UUID --config=metrics_data --config=nonsense foo:bar" ]]; then
-   echo "b args are malformed"
-   echo "Expected : build --profile=$OUT_DIR/bazel_metrics-profile --config=bp2build  --invocation_id=$BES_UUID --config=metrics_data --config=nonsense foo:bar"
-   echo "Actual: $b_args"
-   exit 1
-fi
-
-b_args=$(formulate_b_args "build --config=nonsense --disable_bes --package_path \"my package\" foo:bar")
-
-if [[ $b_args != "build --profile=$OUT_DIR/bazel_metrics-profile --config=bp2build --invocation_id=$BES_UUID --config=nonsense --package_path \"my package\" foo:bar" ]]; then
-   echo "b args are malformed"
-   echo "Expected : build --profile=$OUT_DIR/bazel_metrics-profile --config=bp2build  --invocation_id=$BES_UUID --config=nonsense --package_path \"my package\" foo:bar"
-   echo "Actual: $b_args"
-   exit 1
-fi
-
-# Test with startup option
-b_args=$(formulate_b_args "--batch build --config=nonsense --disable_bes --package_path \"my package\" foo:bar")
-if [[ $b_args != "--batch build --profile=$OUT_DIR/bazel_metrics-profile --config=bp2build --invocation_id=$BES_UUID --config=nonsense --package_path \"my package\" foo:bar" ]]; then
-   echo "b args are malformed"
-   echo "Expected : --batch build --profile=$OUT_DIR/bazel_metrics-profile --config=bp2build  --invocation_id=$BES_UUID --config=nonsense --package_path \"my package\" foo:bar"
-   echo "Actual: $b_args"
-   exit 1
-fi
-
-OUT_DIR="mock_out"
-TEST_PROFILE_OUT=$(get_profile_out_dir)
-if [[ $TEST_PROFILE_OUT != "mock_out" ]]; then
-   echo "Profile Out is malformed."
-   echo "Expected: mock_out"
-   echo "Actual: $TEST_PROFILE_OUT"
-   exit 1
-fi
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index 715f976..5a660e9 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -577,20 +577,6 @@
 
 }
 
-function test_queryview_null_build() {
-  setup
-
-  run_soong queryview
-  local -r output_mtime1=$(stat -c "%y" out/soong/queryview.marker)
-
-  run_soong queryview
-  local -r output_mtime2=$(stat -c "%y" out/soong/queryview.marker)
-
-  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
-    fail "Queryview marker file changed on null build"
-  fi
-}
-
 # This test verifies that adding a new glob to a blueprint file only
 # causes build."${target_product}".ninja to be regenerated on the *next* build, and *not*
 # the build after. (This is a regression test for a bug where globs
diff --git a/tradefed_modules/test_module_config_test.go b/tradefed_modules/test_module_config_test.go
index f76a152..cf6c7d1 100644
--- a/tradefed_modules/test_module_config_test.go
+++ b/tradefed_modules/test_module_config_test.go
@@ -123,24 +123,24 @@
 // Ensure we error for a base we don't support.
 func TestModuleConfigWithHostBaseShouldFailWithExplicitMessage(t *testing.T) {
 	badBp := `
-		java_test_host {
-			name: "base",
-                        srcs: ["a.java"],
+        java_test {
+            name: "base",
+            srcs: ["a.java"],
 		}
 
-                test_module_config {
-                        name: "derived_test",
-                        base: "base",
-                        exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
-                        include_annotations: ["android.platform.test.annotations.LargeTest"],
-                        test_suites: ["general-tests"],
-                }`
+        test_module_config {
+            name: "derived_test",
+            base: "base",
+            exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+            include_annotations: ["android.platform.test.annotations.LargeTest"],
+            test_suites: ["general-tests"],
+        }`
 
 	android.GroupFixturePreparers(
 		java.PrepareForTestWithJavaDefaultModules,
 		android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
 	).ExtendWithErrorHandler(
-		android.FixtureExpectsAtLeastOneErrorMatchingPattern("'java_test_host' module used as base, but 'android_test' expected")).
+		android.FixtureExpectsAtLeastOneErrorMatchingPattern("'base' module used as base but it is not a 'android_test' module.")).
 		RunTestWithBp(t, badBp)
 }
 
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index fcf29c5..1f842f5 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -35,7 +35,6 @@
         "blueprint",
         "blueprint-bootstrap",
         "blueprint-microfactory",
-        "soong-android",
         "soong-elf",
         "soong-finder",
         "soong-remoteexec",
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index a8044df..c54d55f 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -16,8 +16,6 @@
 
 import (
 	"strings"
-
-	"android/soong/android"
 )
 
 var androidmk_denylist []string = []string{
@@ -82,13 +80,21 @@
 	"external/webp/",
 }
 
-func ignoreNdkAndroidMks(androidMks []string) []string {
-	return android.FilterListPred(androidMks, func(s string) bool {
+func ignoreNdkAndroidMks(androidMks []string) (filtered []string) {
+	filter := func(s string) bool {
 		for _, d := range external_ndk_androidmks {
 			if strings.HasPrefix(s, d) {
 				return false
 			}
 		}
 		return true
-	})
+	}
+
+	for _, l := range androidMks {
+		if filter(l) {
+			filtered = append(filtered, l)
+		}
+	}
+
+	return
 }
diff --git a/ui/build/build.go b/ui/build/build.go
index 28c3284..d5a20b4 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -428,7 +428,7 @@
 	if !config.SoongBuildInvocationNeeded() {
 		// This means that the output of soong_build is not needed and thus it would
 		// run unnecessarily. In addition, if this code wasn't there invocations
-		// with only special-cased target names like "m bp2build" would result in
+		// with only special-cased target names would result in
 		// passing Ninja the empty target list and it would then build the default
 		// targets which is not what the user asked for.
 		what = what &^ RunNinja
diff --git a/ui/build/config.go b/ui/build/config.go
index 9ec04a0..f925a0c 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -68,7 +68,6 @@
 
 type configImpl struct {
 	// Some targets that are implemented in soong_build
-	// (bp2build, json-module-graph) are not here and have their own bits below.
 	arguments     []string
 	goma          bool
 	environ       *Environment
@@ -83,7 +82,6 @@
 	checkbuild               bool
 	dist                     bool
 	jsonModuleGraph          bool
-	queryview                bool
 	reportMkMetrics          bool // Collect and report mk2bp migration progress metrics.
 	soongDocs                bool
 	skipConfig               bool
@@ -911,8 +909,6 @@
 			c.dist = true
 		} else if arg == "json-module-graph" {
 			c.jsonModuleGraph = true
-		} else if arg == "queryview" {
-			c.queryview = true
 		} else if arg == "soong_docs" {
 			c.soongDocs = true
 		} else {
@@ -1007,7 +1003,7 @@
 		return true
 	}
 
-	if !c.JsonModuleGraph() && !c.Queryview() && !c.SoongDocs() {
+	if !c.JsonModuleGraph() && !c.SoongDocs() {
 		// Command line was empty, the default Ninja target is built
 		return true
 	}
@@ -1080,10 +1076,6 @@
 	return shared.JoinPath(c.SoongOutDir(), "docs/soong_build.html")
 }
 
-func (c *configImpl) QueryviewMarkerFile() string {
-	return shared.JoinPath(c.SoongOutDir(), "queryview.marker")
-}
-
 func (c *configImpl) ModuleGraphFile() string {
 	return shared.JoinPath(c.SoongOutDir(), "module-graph.json")
 }
@@ -1121,10 +1113,6 @@
 	return c.jsonModuleGraph
 }
 
-func (c *configImpl) Queryview() bool {
-	return c.queryview
-}
-
 func (c *configImpl) SoongDocs() bool {
 	return c.soongDocs
 }
@@ -1341,7 +1329,7 @@
 
 func (c *configImpl) UseRBE() bool {
 	// These alternate modes of running Soong do not use RBE / reclient.
-	if c.Queryview() || c.JsonModuleGraph() {
+	if c.JsonModuleGraph() {
 		return false
 	}
 
diff --git a/ui/build/soong.go b/ui/build/soong.go
index f70d9b7..cd20a4a 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -52,7 +52,6 @@
 
 	soongBuildTag      = "build"
 	jsonModuleGraphTag = "modulegraph"
-	queryviewTag       = "queryview"
 	soongDocsTag       = "soong_docs"
 
 	// bootstrapEpoch is used to determine if an incremental build is incompatible with the current
@@ -307,8 +306,6 @@
 		mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--incremental-build-actions")
 	}
 
-	queryviewDir := filepath.Join(config.SoongOutDir(), "queryview")
-
 	pbfs := []PrimaryBuilderFactory{
 		{
 			name:         soongBuildTag,
@@ -328,15 +325,6 @@
 			),
 		},
 		{
-			name:        queryviewTag,
-			description: fmt.Sprintf("generating the Soong module graph as a Bazel workspace at %s", queryviewDir),
-			config:      config,
-			output:      config.QueryviewMarkerFile(),
-			specificArgs: append(baseArgs,
-				"--bazel_queryview_dir", queryviewDir,
-			),
-		},
-		{
 			name:        soongDocsTag,
 			description: fmt.Sprintf("generating Soong docs at %s", config.SoongDocsHtml()),
 			config:      config,
@@ -572,10 +560,6 @@
 			checkEnvironmentFile(ctx, soongBuildEnv, config.UsedEnvFile(jsonModuleGraphTag))
 		}
 
-		if config.Queryview() {
-			checkEnvironmentFile(ctx, soongBuildEnv, config.UsedEnvFile(queryviewTag))
-		}
-
 		if config.SoongDocs() {
 			checkEnvironmentFile(ctx, soongBuildEnv, config.UsedEnvFile(soongDocsTag))
 		}
@@ -670,10 +654,6 @@
 		targets = append(targets, config.ModuleGraphFile())
 	}
 
-	if config.Queryview() {
-		targets = append(targets, config.QueryviewMarkerFile())
-	}
-
 	if config.SoongDocs() {
 		targets = append(targets, config.SoongDocsHtml())
 	}
diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp
index bd1517c..cf045fd 100644
--- a/ui/metrics/Android.bp
+++ b/ui/metrics/Android.bp
@@ -21,8 +21,6 @@
     pkgPath: "android/soong/ui/metrics",
     deps: [
         "golang-protobuf-proto",
-        "soong-ui-bp2build_metrics_proto",
-        "soong-ui-bazel_metrics_proto",
         "soong-ui-metrics_upload_proto",
         "soong-ui-metrics_proto",
         "soong-ui-mk_metrics_proto",
@@ -62,30 +60,6 @@
 }
 
 bootstrap_go_package {
-    name: "soong-ui-bp2build_metrics_proto",
-    pkgPath: "android/soong/ui/metrics/bp2build_metrics_proto",
-    deps: [
-        "golang-protobuf-reflect-protoreflect",
-        "golang-protobuf-runtime-protoimpl",
-    ],
-    srcs: [
-        "bp2build_metrics_proto/bp2build_metrics.pb.go",
-    ],
-}
-
-bootstrap_go_package {
-    name: "soong-ui-bazel_metrics_proto",
-    pkgPath: "android/soong/ui/metrics/bazel_metrics_proto",
-    deps: [
-        "golang-protobuf-reflect-protoreflect",
-        "golang-protobuf-runtime-protoimpl",
-    ],
-    srcs: [
-        "bazel_metrics_proto/bazel_metrics.pb.go",
-    ],
-}
-
-bootstrap_go_package {
     name: "soong-ui-mk_metrics_proto",
     pkgPath: "android/soong/ui/metrics/mk_metrics_proto",
     deps: [
diff --git a/ui/metrics/BUILD.bazel b/ui/metrics/BUILD.bazel
deleted file mode 100644
index ca39c59..0000000
--- a/ui/metrics/BUILD.bazel
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2023 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("//build/bazel/rules/python:py_proto.bzl", "py_proto_library")
-
-py_proto_library(
-    name = "metrics-py-proto",
-    visibility = ["//build/bazel/scripts:__subpackages__"],
-    deps = [":metrics-proto"],
-)
-
-proto_library(
-    name = "metrics-proto",
-    srcs = [
-        "bazel_metrics_proto/bazel_metrics.proto",
-        "bp2build_metrics_proto/bp2build_metrics.proto",
-        "metrics_proto/metrics.proto",
-    ],
-    strip_import_prefix = "",
-)
diff --git a/ui/metrics/bazel_metrics_proto/bazel_metrics.pb.go b/ui/metrics/bazel_metrics_proto/bazel_metrics.pb.go
deleted file mode 100644
index 8b97b83..0000000
--- a/ui/metrics/bazel_metrics_proto/bazel_metrics.pb.go
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2022 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.30.0
-// 	protoc        v3.21.12
-// source: bazel_metrics.proto
-
-package bazel_metrics_proto
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type BazelMetrics struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	PhaseTimings []*PhaseTiming `protobuf:"bytes,1,rep,name=phase_timings,json=phaseTimings,proto3" json:"phase_timings,omitempty"`
-	Total        *int64         `protobuf:"varint,2,opt,name=total,proto3,oneof" json:"total,omitempty"`
-	ExitCode     *int32         `protobuf:"varint,3,opt,name=exit_code,json=exitCode,proto3,oneof" json:"exit_code,omitempty"`
-	BesId        *string        `protobuf:"bytes,4,opt,name=bes_id,json=besId,proto3,oneof" json:"bes_id,omitempty"`
-}
-
-func (x *BazelMetrics) Reset() {
-	*x = BazelMetrics{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_bazel_metrics_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *BazelMetrics) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*BazelMetrics) ProtoMessage() {}
-
-func (x *BazelMetrics) ProtoReflect() protoreflect.Message {
-	mi := &file_bazel_metrics_proto_msgTypes[0]
-	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 BazelMetrics.ProtoReflect.Descriptor instead.
-func (*BazelMetrics) Descriptor() ([]byte, []int) {
-	return file_bazel_metrics_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *BazelMetrics) GetPhaseTimings() []*PhaseTiming {
-	if x != nil {
-		return x.PhaseTimings
-	}
-	return nil
-}
-
-func (x *BazelMetrics) GetTotal() int64 {
-	if x != nil && x.Total != nil {
-		return *x.Total
-	}
-	return 0
-}
-
-func (x *BazelMetrics) GetExitCode() int32 {
-	if x != nil && x.ExitCode != nil {
-		return *x.ExitCode
-	}
-	return 0
-}
-
-func (x *BazelMetrics) GetBesId() string {
-	if x != nil && x.BesId != nil {
-		return *x.BesId
-	}
-	return ""
-}
-
-type PhaseTiming struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	// E.g. "execution", "analysis", "launch"
-	PhaseName     *string `protobuf:"bytes,1,opt,name=phase_name,json=phaseName,proto3,oneof" json:"phase_name,omitempty"`
-	DurationNanos *int64  `protobuf:"varint,2,opt,name=duration_nanos,json=durationNanos,proto3,oneof" json:"duration_nanos,omitempty"`
-	// What portion of the build time this phase took, with ten-thousandths precision.
-	// E.g., 1111 = 11.11%, 111 = 1.11%
-	PortionOfBuildTime *int32 `protobuf:"varint,3,opt,name=portion_of_build_time,json=portionOfBuildTime,proto3,oneof" json:"portion_of_build_time,omitempty"`
-}
-
-func (x *PhaseTiming) Reset() {
-	*x = PhaseTiming{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_bazel_metrics_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *PhaseTiming) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*PhaseTiming) ProtoMessage() {}
-
-func (x *PhaseTiming) ProtoReflect() protoreflect.Message {
-	mi := &file_bazel_metrics_proto_msgTypes[1]
-	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 PhaseTiming.ProtoReflect.Descriptor instead.
-func (*PhaseTiming) Descriptor() ([]byte, []int) {
-	return file_bazel_metrics_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *PhaseTiming) GetPhaseName() string {
-	if x != nil && x.PhaseName != nil {
-		return *x.PhaseName
-	}
-	return ""
-}
-
-func (x *PhaseTiming) GetDurationNanos() int64 {
-	if x != nil && x.DurationNanos != nil {
-		return *x.DurationNanos
-	}
-	return 0
-}
-
-func (x *PhaseTiming) GetPortionOfBuildTime() int32 {
-	if x != nil && x.PortionOfBuildTime != nil {
-		return *x.PortionOfBuildTime
-	}
-	return 0
-}
-
-var File_bazel_metrics_proto protoreflect.FileDescriptor
-
-var file_bazel_metrics_proto_rawDesc = []byte{
-	0x0a, 0x13, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69,
-	0x6c, 0x64, 0x5f, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73,
-	0x22, 0xd7, 0x01, 0x0a, 0x0c, 0x42, 0x61, 0x7a, 0x65, 0x6c, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
-	0x73, 0x12, 0x4b, 0x0a, 0x0d, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x69, 0x6e,
-	0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
-	0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x5f, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x2e, 0x50, 0x68, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67,
-	0x52, 0x0c, 0x70, 0x68, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x19,
-	0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52,
-	0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x09, 0x65, 0x78, 0x69,
-	0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x08,
-	0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x06, 0x62,
-	0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x05, 0x62,
-	0x65, 0x73, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x74, 0x6f, 0x74, 0x61,
-	0x6c, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x42,
-	0x09, 0x0a, 0x07, 0x5f, 0x62, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x22, 0xd1, 0x01, 0x0a, 0x0b, 0x50,
-	0x68, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x22, 0x0a, 0x0a, 0x70, 0x68,
-	0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
-	0x52, 0x09, 0x70, 0x68, 0x61, 0x73, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x2a,
-	0x0a, 0x0e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x73,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x0d, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x15, 0x70, 0x6f,
-	0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x66, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74,
-	0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, 0x12, 0x70, 0x6f, 0x72,
-	0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x66, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x88,
-	0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x70, 0x68, 0x61, 0x73, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
-	0x65, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e,
-	0x61, 0x6e, 0x6f, 0x73, 0x42, 0x18, 0x0a, 0x16, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e,
-	0x5f, 0x6f, 0x66, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x2e,
-	0x5a, 0x2c, 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, 0x62, 0x61, 0x7a, 0x65, 0x6c,
-	0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-}
-
-var (
-	file_bazel_metrics_proto_rawDescOnce sync.Once
-	file_bazel_metrics_proto_rawDescData = file_bazel_metrics_proto_rawDesc
-)
-
-func file_bazel_metrics_proto_rawDescGZIP() []byte {
-	file_bazel_metrics_proto_rawDescOnce.Do(func() {
-		file_bazel_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_bazel_metrics_proto_rawDescData)
-	})
-	return file_bazel_metrics_proto_rawDescData
-}
-
-var file_bazel_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
-var file_bazel_metrics_proto_goTypes = []interface{}{
-	(*BazelMetrics)(nil), // 0: soong_build_bazel_metrics.BazelMetrics
-	(*PhaseTiming)(nil),  // 1: soong_build_bazel_metrics.PhaseTiming
-}
-var file_bazel_metrics_proto_depIdxs = []int32{
-	1, // 0: soong_build_bazel_metrics.BazelMetrics.phase_timings:type_name -> soong_build_bazel_metrics.PhaseTiming
-	1, // [1:1] is the sub-list for method output_type
-	1, // [1:1] is the sub-list for method input_type
-	1, // [1:1] is the sub-list for extension type_name
-	1, // [1:1] is the sub-list for extension extendee
-	0, // [0:1] is the sub-list for field type_name
-}
-
-func init() { file_bazel_metrics_proto_init() }
-func file_bazel_metrics_proto_init() {
-	if File_bazel_metrics_proto != nil {
-		return
-	}
-	if !protoimpl.UnsafeEnabled {
-		file_bazel_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*BazelMetrics); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_bazel_metrics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*PhaseTiming); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-	}
-	file_bazel_metrics_proto_msgTypes[0].OneofWrappers = []interface{}{}
-	file_bazel_metrics_proto_msgTypes[1].OneofWrappers = []interface{}{}
-	type x struct{}
-	out := protoimpl.TypeBuilder{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_bazel_metrics_proto_rawDesc,
-			NumEnums:      0,
-			NumMessages:   2,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_bazel_metrics_proto_goTypes,
-		DependencyIndexes: file_bazel_metrics_proto_depIdxs,
-		MessageInfos:      file_bazel_metrics_proto_msgTypes,
-	}.Build()
-	File_bazel_metrics_proto = out.File
-	file_bazel_metrics_proto_rawDesc = nil
-	file_bazel_metrics_proto_goTypes = nil
-	file_bazel_metrics_proto_depIdxs = nil
-}
diff --git a/ui/metrics/bazel_metrics_proto/bazel_metrics.proto b/ui/metrics/bazel_metrics_proto/bazel_metrics.proto
deleted file mode 100644
index e45d2bf..0000000
--- a/ui/metrics/bazel_metrics_proto/bazel_metrics.proto
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2022 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package soong_build_bazel_metrics;
-option go_package = "android/soong/ui/metrics/bazel_metrics_proto";
-
-message BazelMetrics {
-  repeated PhaseTiming phase_timings = 1;
-  optional int64 total = 2;
-  optional int32 exit_code = 3;
-  optional string bes_id = 4;
-}
-
-message PhaseTiming {
-  // E.g. "execution", "analysis", "launch"
-  optional string phase_name = 1;
-  optional int64 duration_nanos = 2;
-  // What portion of the build time this phase took, with ten-thousandths precision.
-  // E.g., 1111 = 11.11%, 111 = 1.11%
-  optional int32 portion_of_build_time = 3;
-}
diff --git a/ui/metrics/bazel_metrics_proto/regen.sh b/ui/metrics/bazel_metrics_proto/regen.sh
deleted file mode 100755
index 2cf2bf6..0000000
--- a/ui/metrics/bazel_metrics_proto/regen.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash -e
-
-# Copyright 2022 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Generates the golang source file of bp2build_metrics.proto protobuf file.
-
-function die() { echo "ERROR: $1" >&2; exit 1; }
-
-readonly error_msg="Maybe you need to run 'lunch aosp_arm-eng && m aprotoc blueprint_tools'?"
-
-if ! hash aprotoc &>/dev/null; then
-  die "could not find aprotoc. ${error_msg}"
-fi
-
-if ! aprotoc --go_out=paths=source_relative:. bazel_metrics.proto; then
-  die "build failed. ${error_msg}"
-fi
diff --git a/ui/metrics/bp2build_metrics_proto/bp2build_metrics.pb.go b/ui/metrics/bp2build_metrics_proto/bp2build_metrics.pb.go
deleted file mode 100644
index b34c2b6..0000000
--- a/ui/metrics/bp2build_metrics_proto/bp2build_metrics.pb.go
+++ /dev/null
@@ -1,590 +0,0 @@
-// Copyright 2021 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// 	protoc-gen-go v1.30.0
-// 	protoc        v3.21.12
-// source: bp2build_metrics.proto
-
-package bp2build_metrics_proto
-
-import (
-	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
-	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
-	reflect "reflect"
-	sync "sync"
-)
-
-const (
-	// Verify that this generated code is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-	// Verify that runtime/protoimpl is sufficiently up-to-date.
-	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type UnconvertedReasonType int32
-
-const (
-	// Bp2build does not know how to convert this specific module for some reason
-	// not covered by other reason types. The reason detail should explain the
-	// specific issue.
-	UnconvertedReasonType_UNSUPPORTED UnconvertedReasonType = 0
-	// The module was already defined in a BUILD file available in the source tree.
-	UnconvertedReasonType_DEFINED_IN_BUILD_FILE UnconvertedReasonType = 1
-	// The module was explicitly denylisted by name.
-	UnconvertedReasonType_DENYLISTED UnconvertedReasonType = 2
-	// The module's type has no bp2build implementation.
-	UnconvertedReasonType_TYPE_UNSUPPORTED UnconvertedReasonType = 3
-	// The module has a property not yet supported. The detail field should
-	// name the unsupported property name.
-	UnconvertedReasonType_PROPERTY_UNSUPPORTED UnconvertedReasonType = 4
-	// The module has an unconverted dependency. The detail should consist of
-	// the name of the unconverted module.
-	UnconvertedReasonType_UNCONVERTED_DEP UnconvertedReasonType = 5
-	// The module has a source file with the same name as the module itself.
-	UnconvertedReasonType_SRC_NAME_COLLISION UnconvertedReasonType = 6
-)
-
-// Enum value maps for UnconvertedReasonType.
-var (
-	UnconvertedReasonType_name = map[int32]string{
-		0: "UNSUPPORTED",
-		1: "DEFINED_IN_BUILD_FILE",
-		2: "DENYLISTED",
-		3: "TYPE_UNSUPPORTED",
-		4: "PROPERTY_UNSUPPORTED",
-		5: "UNCONVERTED_DEP",
-		6: "SRC_NAME_COLLISION",
-	}
-	UnconvertedReasonType_value = map[string]int32{
-		"UNSUPPORTED":           0,
-		"DEFINED_IN_BUILD_FILE": 1,
-		"DENYLISTED":            2,
-		"TYPE_UNSUPPORTED":      3,
-		"PROPERTY_UNSUPPORTED":  4,
-		"UNCONVERTED_DEP":       5,
-		"SRC_NAME_COLLISION":    6,
-	}
-)
-
-func (x UnconvertedReasonType) Enum() *UnconvertedReasonType {
-	p := new(UnconvertedReasonType)
-	*p = x
-	return p
-}
-
-func (x UnconvertedReasonType) String() string {
-	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (UnconvertedReasonType) Descriptor() protoreflect.EnumDescriptor {
-	return file_bp2build_metrics_proto_enumTypes[0].Descriptor()
-}
-
-func (UnconvertedReasonType) Type() protoreflect.EnumType {
-	return &file_bp2build_metrics_proto_enumTypes[0]
-}
-
-func (x UnconvertedReasonType) Number() protoreflect.EnumNumber {
-	return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use UnconvertedReasonType.Descriptor instead.
-func (UnconvertedReasonType) EnumDescriptor() ([]byte, []int) {
-	return file_bp2build_metrics_proto_rawDescGZIP(), []int{0}
-}
-
-type Bp2BuildMetrics struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	// Total number of Soong modules converted to generated targets
-	GeneratedModuleCount uint64 `protobuf:"varint,1,opt,name=generatedModuleCount,proto3" json:"generatedModuleCount,omitempty"`
-	// Total number of Soong modules converted to handcrafted targets
-	HandCraftedModuleCount uint64 `protobuf:"varint,2,opt,name=handCraftedModuleCount,proto3" json:"handCraftedModuleCount,omitempty"`
-	// Total number of unconverted Soong modules
-	UnconvertedModuleCount uint64 `protobuf:"varint,3,opt,name=unconvertedModuleCount,proto3" json:"unconvertedModuleCount,omitempty"`
-	// Counts of symlinks in synthetic bazel workspace
-	WorkspaceSymlinkCount uint64 `protobuf:"varint,9,opt,name=workspaceSymlinkCount,proto3" json:"workspaceSymlinkCount,omitempty"`
-	// Counts of mkdir calls during creation of synthetic bazel workspace
-	WorkspaceMkDirCount uint64 `protobuf:"varint,10,opt,name=workspaceMkDirCount,proto3" json:"workspaceMkDirCount,omitempty"`
-	// Counts of generated Bazel targets per Bazel rule class
-	RuleClassCount map[string]uint64 `protobuf:"bytes,4,rep,name=ruleClassCount,proto3" json:"ruleClassCount,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
-	// List of converted modules
-	ConvertedModules []string `protobuf:"bytes,5,rep,name=convertedModules,proto3" json:"convertedModules,omitempty"`
-	// Unconverted modules, mapped to the reason the module was not converted.
-	UnconvertedModules map[string]*UnconvertedReason `protobuf:"bytes,11,rep,name=unconvertedModules,proto3" json:"unconvertedModules,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	// Counts of converted modules by module type.
-	ConvertedModuleTypeCount map[string]uint64 `protobuf:"bytes,6,rep,name=convertedModuleTypeCount,proto3" json:"convertedModuleTypeCount,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
-	// Counts of total modules by module type.
-	TotalModuleTypeCount map[string]uint64 `protobuf:"bytes,7,rep,name=totalModuleTypeCount,proto3" json:"totalModuleTypeCount,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
-	// List of traced runtime events of bp2build, useful for tracking bp2build
-	// runtime.
-	Events []*Event `protobuf:"bytes,8,rep,name=events,proto3" json:"events,omitempty"`
-}
-
-func (x *Bp2BuildMetrics) Reset() {
-	*x = Bp2BuildMetrics{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_bp2build_metrics_proto_msgTypes[0]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *Bp2BuildMetrics) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Bp2BuildMetrics) ProtoMessage() {}
-
-func (x *Bp2BuildMetrics) ProtoReflect() protoreflect.Message {
-	mi := &file_bp2build_metrics_proto_msgTypes[0]
-	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 Bp2BuildMetrics.ProtoReflect.Descriptor instead.
-func (*Bp2BuildMetrics) Descriptor() ([]byte, []int) {
-	return file_bp2build_metrics_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Bp2BuildMetrics) GetGeneratedModuleCount() uint64 {
-	if x != nil {
-		return x.GeneratedModuleCount
-	}
-	return 0
-}
-
-func (x *Bp2BuildMetrics) GetHandCraftedModuleCount() uint64 {
-	if x != nil {
-		return x.HandCraftedModuleCount
-	}
-	return 0
-}
-
-func (x *Bp2BuildMetrics) GetUnconvertedModuleCount() uint64 {
-	if x != nil {
-		return x.UnconvertedModuleCount
-	}
-	return 0
-}
-
-func (x *Bp2BuildMetrics) GetWorkspaceSymlinkCount() uint64 {
-	if x != nil {
-		return x.WorkspaceSymlinkCount
-	}
-	return 0
-}
-
-func (x *Bp2BuildMetrics) GetWorkspaceMkDirCount() uint64 {
-	if x != nil {
-		return x.WorkspaceMkDirCount
-	}
-	return 0
-}
-
-func (x *Bp2BuildMetrics) GetRuleClassCount() map[string]uint64 {
-	if x != nil {
-		return x.RuleClassCount
-	}
-	return nil
-}
-
-func (x *Bp2BuildMetrics) GetConvertedModules() []string {
-	if x != nil {
-		return x.ConvertedModules
-	}
-	return nil
-}
-
-func (x *Bp2BuildMetrics) GetUnconvertedModules() map[string]*UnconvertedReason {
-	if x != nil {
-		return x.UnconvertedModules
-	}
-	return nil
-}
-
-func (x *Bp2BuildMetrics) GetConvertedModuleTypeCount() map[string]uint64 {
-	if x != nil {
-		return x.ConvertedModuleTypeCount
-	}
-	return nil
-}
-
-func (x *Bp2BuildMetrics) GetTotalModuleTypeCount() map[string]uint64 {
-	if x != nil {
-		return x.TotalModuleTypeCount
-	}
-	return nil
-}
-
-func (x *Bp2BuildMetrics) GetEvents() []*Event {
-	if x != nil {
-		return x.Events
-	}
-	return nil
-}
-
-// Traced runtime event of bp2build.
-type Event struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	// The event name.
-	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
-	// The absolute start time of the event
-	// The number of nanoseconds elapsed since January 1, 1970 UTC.
-	StartTime uint64 `protobuf:"varint,2,opt,name=start_time,json=startTime,proto3" json:"start_time,omitempty"`
-	// The real running time.
-	// The number of nanoseconds elapsed since start_time.
-	RealTime uint64 `protobuf:"varint,3,opt,name=real_time,json=realTime,proto3" json:"real_time,omitempty"`
-}
-
-func (x *Event) Reset() {
-	*x = Event{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_bp2build_metrics_proto_msgTypes[1]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *Event) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Event) ProtoMessage() {}
-
-func (x *Event) ProtoReflect() protoreflect.Message {
-	mi := &file_bp2build_metrics_proto_msgTypes[1]
-	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 Event.ProtoReflect.Descriptor instead.
-func (*Event) Descriptor() ([]byte, []int) {
-	return file_bp2build_metrics_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *Event) GetName() string {
-	if x != nil {
-		return x.Name
-	}
-	return ""
-}
-
-func (x *Event) GetStartTime() uint64 {
-	if x != nil {
-		return x.StartTime
-	}
-	return 0
-}
-
-func (x *Event) GetRealTime() uint64 {
-	if x != nil {
-		return x.RealTime
-	}
-	return 0
-}
-
-type UnconvertedReason struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	// The type of reason that the module could not be converted.
-	Type UnconvertedReasonType `protobuf:"varint,1,opt,name=type,proto3,enum=soong_build_bp2build_metrics.UnconvertedReasonType" json:"type,omitempty"`
-	// Descriptive details describing why the module could not be converted.
-	// This detail should be kept very short and should be in the context of
-	// the type. (Otherwise, this would significantly bloat metrics.)
-	Detail string `protobuf:"bytes,2,opt,name=detail,proto3" json:"detail,omitempty"`
-}
-
-func (x *UnconvertedReason) Reset() {
-	*x = UnconvertedReason{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_bp2build_metrics_proto_msgTypes[2]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *UnconvertedReason) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*UnconvertedReason) ProtoMessage() {}
-
-func (x *UnconvertedReason) ProtoReflect() protoreflect.Message {
-	mi := &file_bp2build_metrics_proto_msgTypes[2]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use UnconvertedReason.ProtoReflect.Descriptor instead.
-func (*UnconvertedReason) Descriptor() ([]byte, []int) {
-	return file_bp2build_metrics_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *UnconvertedReason) GetType() UnconvertedReasonType {
-	if x != nil {
-		return x.Type
-	}
-	return UnconvertedReasonType_UNSUPPORTED
-}
-
-func (x *UnconvertedReason) GetDetail() string {
-	if x != nil {
-		return x.Detail
-	}
-	return ""
-}
-
-var File_bp2build_metrics_proto protoreflect.FileDescriptor
-
-var file_bp2build_metrics_proto_rawDesc = []byte{
-	0x0a, 0x16, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
-	0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
-	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0xc0, 0x09, 0x0a, 0x0f, 0x42, 0x70, 0x32, 0x42, 0x75,
-	0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x67, 0x65,
-	0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x75,
-	0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61,
-	0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x36,
-	0x0a, 0x16, 0x68, 0x61, 0x6e, 0x64, 0x43, 0x72, 0x61, 0x66, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64,
-	0x75, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16,
-	0x68, 0x61, 0x6e, 0x64, 0x43, 0x72, 0x61, 0x66, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
-	0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x16, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x76,
-	0x65, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x16, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72,
-	0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34,
-	0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69,
-	0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x77,
-	0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x43,
-	0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
-	0x65, 0x4d, 0x6b, 0x44, 0x69, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28,
-	0x04, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4d, 0x6b, 0x44, 0x69,
-	0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x69, 0x0a, 0x0e, 0x72, 0x75, 0x6c, 0x65, 0x43, 0x6c,
-	0x61, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41,
-	0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32,
-	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x42, 0x70,
-	0x32, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x52, 0x75,
-	0x6c, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72,
-	0x79, 0x52, 0x0e, 0x72, 0x75, 0x6c, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e,
-	0x74, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x6f,
-	0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6e,
-	0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x75, 0x0a,
-	0x12, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75,
-	0x6c, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
-	0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69, 0x6c, 0x64,
-	0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x42, 0x70, 0x32, 0x42, 0x75, 0x69, 0x6c,
-	0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65,
-	0x72, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
-	0x52, 0x12, 0x75, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64,
-	0x75, 0x6c, 0x65, 0x73, 0x12, 0x87, 0x01, 0x0a, 0x18, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74,
-	0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e,
-	0x74, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
-	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x42, 0x70, 0x32, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x4d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64,
-	0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45,
-	0x6e, 0x74, 0x72, 0x79, 0x52, 0x18, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x4d,
-	0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x7b,
-	0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70,
-	0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x47, 0x2e, 0x73,
-	0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32, 0x62, 0x75,
-	0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x42, 0x70, 0x32, 0x42,
-	0x75, 0x69, 0x6c, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x54, 0x6f, 0x74, 0x61,
-	0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74,
-	0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x6f, 0x64, 0x75,
-	0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x06, 0x65,
-	0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x6f,
-	0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69,
-	0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74,
-	0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x1a, 0x41, 0x0a, 0x13, 0x52, 0x75, 0x6c, 0x65,
-	0x43, 0x6c, 0x61, 0x73, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
-	0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
-	0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04,
-	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x76, 0x0a, 0x17, 0x55,
-	0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
-	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
-	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
-	0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74,
-	0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
-	0x02, 0x38, 0x01, 0x1a, 0x4b, 0x0a, 0x1d, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64,
-	0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45,
-	0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
-	0x1a, 0x47, 0x0a, 0x19, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x54,
-	0x79, 0x70, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
-	0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
-	0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x57, 0x0a, 0x05, 0x45, 0x76, 0x65,
-	0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 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, 0x02, 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, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x61, 0x6c, 0x54, 0x69,
-	0x6d, 0x65, 0x22, 0x74, 0x0a, 0x11, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65,
-	0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x47, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x33, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75,
-	0x69, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x2e, 0x55, 0x6e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64,
-	0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
-	0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x06, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x2a, 0xb0, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x63,
-	0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x54, 0x79,
-	0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45,
-	0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x45, 0x46, 0x49, 0x4e, 0x45, 0x44, 0x5f, 0x49,
-	0x4e, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x0e,
-	0x0a, 0x0a, 0x44, 0x45, 0x4e, 0x59, 0x4c, 0x49, 0x53, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x14,
-	0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54,
-	0x45, 0x44, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x50, 0x45, 0x52, 0x54, 0x59,
-	0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, 0x13,
-	0x0a, 0x0f, 0x55, 0x4e, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x44, 0x45,
-	0x50, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x52, 0x43, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x5f,
-	0x43, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x42, 0x31, 0x5a, 0x2f, 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, 0x62, 0x70, 0x32, 0x62, 0x75, 0x69, 0x6c, 0x64,
-	0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-}
-
-var (
-	file_bp2build_metrics_proto_rawDescOnce sync.Once
-	file_bp2build_metrics_proto_rawDescData = file_bp2build_metrics_proto_rawDesc
-)
-
-func file_bp2build_metrics_proto_rawDescGZIP() []byte {
-	file_bp2build_metrics_proto_rawDescOnce.Do(func() {
-		file_bp2build_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_bp2build_metrics_proto_rawDescData)
-	})
-	return file_bp2build_metrics_proto_rawDescData
-}
-
-var file_bp2build_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_bp2build_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
-var file_bp2build_metrics_proto_goTypes = []interface{}{
-	(UnconvertedReasonType)(0), // 0: soong_build_bp2build_metrics.UnconvertedReasonType
-	(*Bp2BuildMetrics)(nil),    // 1: soong_build_bp2build_metrics.Bp2BuildMetrics
-	(*Event)(nil),              // 2: soong_build_bp2build_metrics.Event
-	(*UnconvertedReason)(nil),  // 3: soong_build_bp2build_metrics.UnconvertedReason
-	nil,                        // 4: soong_build_bp2build_metrics.Bp2BuildMetrics.RuleClassCountEntry
-	nil,                        // 5: soong_build_bp2build_metrics.Bp2BuildMetrics.UnconvertedModulesEntry
-	nil,                        // 6: soong_build_bp2build_metrics.Bp2BuildMetrics.ConvertedModuleTypeCountEntry
-	nil,                        // 7: soong_build_bp2build_metrics.Bp2BuildMetrics.TotalModuleTypeCountEntry
-}
-var file_bp2build_metrics_proto_depIdxs = []int32{
-	4, // 0: soong_build_bp2build_metrics.Bp2BuildMetrics.ruleClassCount:type_name -> soong_build_bp2build_metrics.Bp2BuildMetrics.RuleClassCountEntry
-	5, // 1: soong_build_bp2build_metrics.Bp2BuildMetrics.unconvertedModules:type_name -> soong_build_bp2build_metrics.Bp2BuildMetrics.UnconvertedModulesEntry
-	6, // 2: soong_build_bp2build_metrics.Bp2BuildMetrics.convertedModuleTypeCount:type_name -> soong_build_bp2build_metrics.Bp2BuildMetrics.ConvertedModuleTypeCountEntry
-	7, // 3: soong_build_bp2build_metrics.Bp2BuildMetrics.totalModuleTypeCount:type_name -> soong_build_bp2build_metrics.Bp2BuildMetrics.TotalModuleTypeCountEntry
-	2, // 4: soong_build_bp2build_metrics.Bp2BuildMetrics.events:type_name -> soong_build_bp2build_metrics.Event
-	0, // 5: soong_build_bp2build_metrics.UnconvertedReason.type:type_name -> soong_build_bp2build_metrics.UnconvertedReasonType
-	3, // 6: soong_build_bp2build_metrics.Bp2BuildMetrics.UnconvertedModulesEntry.value:type_name -> soong_build_bp2build_metrics.UnconvertedReason
-	7, // [7:7] is the sub-list for method output_type
-	7, // [7:7] is the sub-list for method input_type
-	7, // [7:7] is the sub-list for extension type_name
-	7, // [7:7] is the sub-list for extension extendee
-	0, // [0:7] is the sub-list for field type_name
-}
-
-func init() { file_bp2build_metrics_proto_init() }
-func file_bp2build_metrics_proto_init() {
-	if File_bp2build_metrics_proto != nil {
-		return
-	}
-	if !protoimpl.UnsafeEnabled {
-		file_bp2build_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Bp2BuildMetrics); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_bp2build_metrics_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*Event); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
-		file_bp2build_metrics_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*UnconvertedReason); 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{
-		File: protoimpl.DescBuilder{
-			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-			RawDescriptor: file_bp2build_metrics_proto_rawDesc,
-			NumEnums:      1,
-			NumMessages:   7,
-			NumExtensions: 0,
-			NumServices:   0,
-		},
-		GoTypes:           file_bp2build_metrics_proto_goTypes,
-		DependencyIndexes: file_bp2build_metrics_proto_depIdxs,
-		EnumInfos:         file_bp2build_metrics_proto_enumTypes,
-		MessageInfos:      file_bp2build_metrics_proto_msgTypes,
-	}.Build()
-	File_bp2build_metrics_proto = out.File
-	file_bp2build_metrics_proto_rawDesc = nil
-	file_bp2build_metrics_proto_goTypes = nil
-	file_bp2build_metrics_proto_depIdxs = nil
-}
diff --git a/ui/metrics/bp2build_metrics_proto/bp2build_metrics.proto b/ui/metrics/bp2build_metrics_proto/bp2build_metrics.proto
deleted file mode 100644
index 49cb2b4..0000000
--- a/ui/metrics/bp2build_metrics_proto/bp2build_metrics.proto
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2021 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-syntax = "proto3";
-
-package soong_build_bp2build_metrics;
-option go_package = "android/soong/ui/metrics/bp2build_metrics_proto";
-
-message Bp2BuildMetrics {
-  // Total number of Soong modules converted to generated targets
-  uint64 generatedModuleCount = 1;
-
-  // Total number of Soong modules converted to handcrafted targets
-  uint64 handCraftedModuleCount = 2;
-
-  // Total number of unconverted Soong modules
-  uint64 unconvertedModuleCount = 3;
-
-  // Counts of symlinks in synthetic bazel workspace
-  uint64 workspaceSymlinkCount= 9;
-
-  // Counts of mkdir calls during creation of synthetic bazel workspace
-  uint64 workspaceMkDirCount= 10;
-
-  // Counts of generated Bazel targets per Bazel rule class
-  map<string, uint64> ruleClassCount = 4;
-
-  // List of converted modules
-  repeated string convertedModules = 5;
-
-  // Unconverted modules, mapped to the reason the module was not converted.
-  map<string, UnconvertedReason> unconvertedModules = 11;
-
-  // Counts of converted modules by module type.
-  map<string, uint64> convertedModuleTypeCount = 6;
-
-  // Counts of total modules by module type.
-  map<string, uint64> totalModuleTypeCount = 7;
-
-  // List of traced runtime events of bp2build, useful for tracking bp2build
-  // runtime.
-  repeated Event events = 8;
-}
-
-// Traced runtime event of bp2build.
-message Event {
-  // The event name.
-  string name = 1;
-
-  // The absolute start time of the event
-  // The number of nanoseconds elapsed since January 1, 1970 UTC.
-  uint64 start_time = 2;
-
-  // The real running time.
-  // The number of nanoseconds elapsed since start_time.
-  uint64 real_time = 3;
-}
-
-message UnconvertedReason {
-  // The type of reason that the module could not be converted.
-  UnconvertedReasonType type = 1;
-
-  // Descriptive details describing why the module could not be converted.
-  // This detail should be kept very short and should be in the context of
-  // the type. (Otherwise, this would significantly bloat metrics.)
-  string detail = 2;
-}
-
-enum UnconvertedReasonType {
-  // Bp2build does not know how to convert this specific module for some reason
-  // not covered by other reason types. The reason detail should explain the
-  // specific issue.
-  UNSUPPORTED = 0;
-
-  // The module was already defined in a BUILD file available in the source tree.
-  DEFINED_IN_BUILD_FILE = 1;
-
-  // The module was explicitly denylisted by name.
-  DENYLISTED = 2;
-
-  // The module's type has no bp2build implementation.
-  TYPE_UNSUPPORTED = 3;
-
-  // The module has a property not yet supported. The detail field should
-  // name the unsupported property name.
-  PROPERTY_UNSUPPORTED = 4;
-
-  // The module has an unconverted dependency. The detail should consist of
-  // the name of the unconverted module.
-  UNCONVERTED_DEP = 5;
-
-  // The module has a source file with the same name as the module itself.
-  SRC_NAME_COLLISION = 6;
-}
\ No newline at end of file
diff --git a/ui/metrics/bp2build_metrics_proto/regen.sh b/ui/metrics/bp2build_metrics_proto/regen.sh
deleted file mode 100755
index bfe4294..0000000
--- a/ui/metrics/bp2build_metrics_proto/regen.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash -e
-
-# Copyright 2021 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Generates the golang source file of bp2build_metrics.proto protobuf file.
-
-function die() { echo "ERROR: $1" >&2; exit 1; }
-
-readonly error_msg="Maybe you need to run 'lunch aosp_arm-eng && m aprotoc blueprint_tools'?"
-
-if ! hash aprotoc &>/dev/null; then
-  die "could not find aprotoc. ${error_msg}"
-fi
-
-if ! aprotoc --go_out=paths=source_relative:. bp2build_metrics.proto; then
-  die "build failed. ${error_msg}"
-fi
diff --git a/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel b/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel
deleted file mode 100644
index f6c6df8..0000000
--- a/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2022 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("//build/bazel/rules/python:py_proto.bzl", "py_proto_library")
-
-proto_library(
-    name = "bp2build_proto",
-    srcs = ["bp2build.proto"],
-    strip_import_prefix = "",
-)
-
-py_proto_library(
-    name = "bp2build_py_proto",
-    visibility = ["//build/bazel/scripts/bp2build_progress:__pkg__"],
-    deps = [":bp2build_proto"],
-)
diff --git a/ui/metrics/bp2build_progress_metrics_proto/bp2build.proto b/ui/metrics/bp2build_progress_metrics_proto/bp2build.proto
deleted file mode 100644
index 5b44002..0000000
--- a/ui/metrics/bp2build_progress_metrics_proto/bp2build.proto
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-syntax = "proto3";
-
-package bp2build_proto;
-
-
-// Conversion progress report for root_modules .
-message Bp2buildConversionProgress {
-
-  // Soong module identifying information.
-  message Module {
-    // Name of the Soong module.
-    string name = 1;
-
-    // Directory that the Soong module is in.
-    string directory = 2;
-
-    // Module type of this module.
-    string type = 3;
-
-    // All unconverted transitive dependencies.
-    repeated string unconverted_deps = 4;
-
-    // Total number of transitive dependencies.
-    int32 num_deps = 5;
-
-    // Unconverted reasons from heuristics
-    repeated string unconverted_reasons_from_heuristics = 6;
-  }
-
-  // Modules that the transitive dependencies were identified for.
-  repeated string root_modules = 1;
-
-  // Names of all dependencies of the root_modules.
-  int32 num_deps = 2;
-
-  // Module with all its unconverted transitive dependencies.
-  repeated Module unconverted = 3;
-}