Merge "Support include/exclude paths for memtag_heap." into main
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 9916451..fb2e0d7 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -228,6 +228,7 @@
 		"frameworks/base/services/tests/servicestests/aidl":  Bp2BuildDefaultTrue,
 		"frameworks/base/startop/apps/test":                  Bp2BuildDefaultTrue,
 		"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
+		"frameworks/base/tools/aapt":                         Bp2BuildDefaultTrue,
 		"frameworks/base/tools/aapt2":                        Bp2BuildDefaultTrue,
 		"frameworks/base/tools/codegen":                      Bp2BuildDefaultTrueRecursively,
 		"frameworks/base/tools/streaming_proto":              Bp2BuildDefaultTrueRecursively,
@@ -909,6 +910,9 @@
 
 		"merge_annotation_zips_test",
 
+		// bouncycastle dep
+		"platform-test-annotations",
+
 		// java_resources with multiple resource_dirs
 		"emma",
 	}
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 42ba9b4..4b98345 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -1382,10 +1382,7 @@
 			WriteFileRuleVerbatim(ctx, out, "")
 		case "FileWrite", "SourceSymlinkManifest":
 			out := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
-			// TODO(b/297366783) This is a hack to make files from skylib's diff_test executable.
-			// We need to update bazel to have aquery tell us whether a file is supposed to be
-			// executable or not.
-			if strings.HasSuffix(buildStatement.OutputPaths[0], "-test.sh") {
+			if buildStatement.IsExecutable {
 				WriteExecutableFileRuleVerbatim(ctx, out, buildStatement.FileContents)
 			} else {
 				WriteFileRuleVerbatim(ctx, out, buildStatement.FileContents)
diff --git a/android/config.go b/android/config.go
index 0b15c79..1a3b539 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1792,30 +1792,6 @@
 	return c.PlatformSepolicyVersion()
 }
 
-func (c *deviceConfig) BoardPlatVendorPolicy() []string {
-	return c.config.productVariables.BoardPlatVendorPolicy
-}
-
-func (c *deviceConfig) BoardReqdMaskPolicy() []string {
-	return c.config.productVariables.BoardReqdMaskPolicy
-}
-
-func (c *deviceConfig) BoardSystemExtPublicPrebuiltDirs() []string {
-	return c.config.productVariables.BoardSystemExtPublicPrebuiltDirs
-}
-
-func (c *deviceConfig) BoardSystemExtPrivatePrebuiltDirs() []string {
-	return c.config.productVariables.BoardSystemExtPrivatePrebuiltDirs
-}
-
-func (c *deviceConfig) BoardProductPublicPrebuiltDirs() []string {
-	return c.config.productVariables.BoardProductPublicPrebuiltDirs
-}
-
-func (c *deviceConfig) BoardProductPrivatePrebuiltDirs() []string {
-	return c.config.productVariables.BoardProductPrivatePrebuiltDirs
-}
-
 func (c *deviceConfig) SystemExtSepolicyPrebuiltApiDir() string {
 	return String(c.config.productVariables.SystemExtSepolicyPrebuiltApiDir)
 }
diff --git a/android/defs.go b/android/defs.go
index 682111e..b28d2fa 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -107,8 +107,8 @@
 
 	Cat = pctx.AndroidStaticRule("Cat",
 		blueprint.RuleParams{
-			Command:     "cat $in > $out",
-			Description: "concatenate licenses $out",
+			Command:     "rm -f $out && cat $in > $out",
+			Description: "concatenate files to $out",
 		})
 
 	// ubuntu 14.04 offcially use dash for /bin/sh, and its builtin echo command
@@ -116,7 +116,7 @@
 	// content to file.
 	writeFile = pctx.AndroidStaticRule("writeFile",
 		blueprint.RuleParams{
-			Command:     `/bin/bash -c 'echo -e -n "$$0" > $out' $content`,
+			Command:     `rm -f $out && /bin/bash -c 'echo -e -n "$$0" > $out' $content`,
 			Description: "writing file $out",
 		},
 		"content")
diff --git a/android/module.go b/android/module.go
index 19502ba..f9ea897 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1371,7 +1371,7 @@
 		for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() {
 			configToBools := enabledPropertyOverrides.ConfigurableValues[axis]
 			for cfg, val := range configToBools {
-				if axis != bazel.OsConfigurationAxis || osSupport[cfg] {
+				if axis != bazel.OsConfigurationAxis || osSupport[cfg] || val /*If enabled is explicitly requested via overrides */ {
 					enabledProperty.SetSelectValue(axis, cfg, &val)
 				}
 			}
diff --git a/android/proto.go b/android/proto.go
index 3c4b4c7..fc21d01 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -350,13 +350,12 @@
 var (
 	protoIncludeDirGeneratedSuffix = ".include_dir_bp2build_generated_proto"
 	protoIncludeDirsBp2buildKey    = NewOnceKey("protoIncludeDirsBp2build")
-	protoIncludeDirsBp2buildLock   sync.Mutex
 )
 
-func getProtoIncludeDirsBp2build(config Config) *map[protoIncludeDirKey]bool {
+func getProtoIncludeDirsBp2build(config Config) *sync.Map {
 	return config.Once(protoIncludeDirsBp2buildKey, func() interface{} {
-		return &map[protoIncludeDirKey]bool{}
-	}).(*map[protoIncludeDirKey]bool)
+		return &sync.Map{}
+	}).(*sync.Map)
 }
 
 // key for dynamically creating proto_library per proto.include_dirs
@@ -370,9 +369,6 @@
 // might create the targets in a subdirectory of `includeDir`
 // Returns the labels of the proto_library targets
 func createProtoLibraryTargetsForIncludeDirs(ctx Bp2buildMutatorContext, includeDirs []string) bazel.LabelList {
-	protoIncludeDirsBp2buildLock.Lock()
-	defer protoIncludeDirsBp2buildLock.Unlock()
-
 	var ret bazel.LabelList
 	for _, dir := range includeDirs {
 		if exists, _, _ := ctx.Config().fs.Exists(filepath.Join(dir, "Android.bp")); !exists {
@@ -389,11 +385,10 @@
 				Label: "//" + pkg + ":" + label,
 			})
 			key := protoIncludeDirKey{dir: dir, subpackgeInDir: pkg}
-			if _, exists := (*dirMap)[key]; exists {
+			if _, exists := dirMap.LoadOrStore(key, true); exists {
 				// A proto_library has already been created for this package relative to this include dir
 				continue
 			}
-			(*dirMap)[key] = true
 			srcs := protoLabelelsPartitionedByPkg[pkg]
 			rel, err := filepath.Rel(dir, pkg)
 			if err != nil {
@@ -413,6 +408,11 @@
 			// As a workarounds, delete `target_compatible_with`
 			alwaysEnabled := bazel.BoolAttribute{}
 			alwaysEnabled.Value = proptools.BoolPtr(true)
+			// Add android and linux explicitly so that fillcommonbp2buildmoduleattrs can override these configs
+			// When we extend b support for other os'es (darwin/windows), we should add those configs here as well
+			alwaysEnabled.SetSelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid, proptools.BoolPtr(true))
+			alwaysEnabled.SetSelectValue(bazel.OsConfigurationAxis, bazel.OsLinux, proptools.BoolPtr(true))
+
 			ctx.CreateBazelTargetModuleWithRestrictions(
 				bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
 				CommonAttributes{
diff --git a/android/variable.go b/android/variable.go
index 8805fe5..89ac915 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -372,17 +372,11 @@
 
 	MultitreeUpdateMeta bool `json:",omitempty"`
 
-	BoardVendorSepolicyDirs           []string `json:",omitempty"`
-	BoardOdmSepolicyDirs              []string `json:",omitempty"`
-	BoardReqdMaskPolicy               []string `json:",omitempty"`
-	BoardPlatVendorPolicy             []string `json:",omitempty"`
-	BoardSystemExtPublicPrebuiltDirs  []string `json:",omitempty"`
-	BoardSystemExtPrivatePrebuiltDirs []string `json:",omitempty"`
-	BoardProductPublicPrebuiltDirs    []string `json:",omitempty"`
-	BoardProductPrivatePrebuiltDirs   []string `json:",omitempty"`
-	SystemExtPublicSepolicyDirs       []string `json:",omitempty"`
-	SystemExtPrivateSepolicyDirs      []string `json:",omitempty"`
-	BoardSepolicyM4Defs               []string `json:",omitempty"`
+	BoardVendorSepolicyDirs      []string `json:",omitempty"`
+	BoardOdmSepolicyDirs         []string `json:",omitempty"`
+	SystemExtPublicSepolicyDirs  []string `json:",omitempty"`
+	SystemExtPrivateSepolicyDirs []string `json:",omitempty"`
+	BoardSepolicyM4Defs          []string `json:",omitempty"`
 
 	BoardSepolicyVers       *string `json:",omitempty"`
 	PlatformSepolicyVersion *string `json:",omitempty"`
diff --git a/bazel/aquery.go b/bazel/aquery.go
index d77d59a..76cd972 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -123,6 +123,7 @@
 	// Unlike most properties in BuildStatement, these paths must be relative to the root of
 	// the whole out/ folder, instead of relative to ctx.Config().BazelContext.OutputBase()
 	ImplicitDeps []string
+	IsExecutable bool
 }
 
 // A helper type for aquery processing which facilitates retrieval of path IDs from their
@@ -560,6 +561,7 @@
 		Mnemonic:          actionEntry.Mnemonic,
 		InputDepsetHashes: depsetHashes,
 		FileContents:      actionEntry.FileContents,
+		IsExecutable:      actionEntry.IsExecutable,
 	}, nil
 }
 
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index c104833..6b50a2e 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -32,6 +32,7 @@
         "soong-genrule",
         "soong-linkerconfig",
         "soong-python",
+        "soong-rust",
         "soong-sh",
         "soong-shared",
         "soong-starlark-format",
@@ -82,6 +83,10 @@
         "python_binary_conversion_test.go",
         "python_library_conversion_test.go",
         "python_test_conversion_test.go",
+        "rust_binary_conversion_test.go",
+        "rust_library_conversion_test.go",
+        "rust_proc_macro_conversion_test.go",
+        "rust_protobuf_conversion_test.go",
         "sh_conversion_test.go",
         "sh_test_conversion_test.go",
         "soong_config_module_type_conversion_test.go",
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index 25494a1..f2ee322 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -47,6 +47,11 @@
 		name: "TestApp",
 		srcs: ["app.java"],
 		sdk_version: "current",
+		optimize: {
+			shrink: true,
+			optimize: true,
+			obfuscate: true,
+		},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -75,17 +80,25 @@
 		},
 		Blueprint: simpleModuleDoNotConvertBp2build("android_app", "static_lib_dep") + `
 android_app {
-		name: "TestApp",
-		srcs: ["app.java"],
-		sdk_version: "current",
-		package_name: "com.google",
-		resource_dirs: ["resa", "resb"],
-		manifest: "manifest/AndroidManifest.xml",
-		static_libs: ["static_lib_dep"],
-		java_version: "7",
-		certificate: "foocert",
-		required: ["static_lib_dep"],
-		asset_dirs: ["assets_"],
+	name: "TestApp",
+	srcs: ["app.java"],
+	sdk_version: "current",
+	package_name: "com.google",
+	resource_dirs: ["resa", "resb"],
+	manifest: "manifest/AndroidManifest.xml",
+	static_libs: ["static_lib_dep"],
+	java_version: "7",
+	certificate: "foocert",
+	required: ["static_lib_dep"],
+	asset_dirs: ["assets_"],
+	optimize: {
+		enabled: true,
+		optimize: false,
+		proguard_flags_files: ["proguard.flags"],
+		shrink: false,
+		obfuscate: false,
+		ignore_warnings: true,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -103,6 +116,14 @@
 				"java_version":     `"7"`,
 				"sdk_version":      `"current"`,
 				"certificate_name": `"foocert"`,
+				"proguard_specs": `[
+        "proguard.flags",
+        ":TestApp_proguard_flags",
+    ]`,
+			}),
+			MakeBazelTarget("genrule", "TestApp_proguard_flags", AttrNameToString{
+				"outs": `["TestApp_proguard.flags"]`,
+				"cmd":  `"echo -ignorewarning -dontshrink -dontoptimize -dontobfuscate > $(OUTS)"`,
 			}),
 		}})
 }
@@ -129,7 +150,10 @@
 		x86: {
 			srcs: ["x86.java"],
 		}
-	}
+	},
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -142,6 +166,7 @@
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `["res/res.png"]`,
 				"sdk_version":    `"current"`,
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -157,6 +182,9 @@
 	name: "TestApp",
 	certificate: ":foocert",
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -165,6 +193,7 @@
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `[]`,
 				"sdk_version":    `"current"`, // use as default
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -182,6 +211,9 @@
 	name: "TestApp",
 	certificate: "foocert",
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -190,6 +222,7 @@
 				"manifest":       `"AndroidManifest.xml"`,
 				"resource_files": `[]`,
 				"sdk_version":    `"current"`, // use as default
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -207,6 +240,9 @@
 	name: "TestApp",
 	certificate: "foocert",
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -215,6 +251,7 @@
 				"manifest":         `"AndroidManifest.xml"`,
 				"resource_files":   `[]`,
 				"sdk_version":      `"current"`, // use as default
+				"optimize":         `False`,
 			}),
 		}})
 }
@@ -225,12 +262,14 @@
 		ModuleTypeUnderTest:        "android_app",
 		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
 		Filesystem:                 map[string]string{},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") +
-			simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
+		Blueprint: simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
 android_app {
 	name: "foo",
 	libs: ["barLib"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -239,6 +278,7 @@
 				"resource_files": `[]`,
 				"deps":           `[":barLib-neverlink"]`,
 				"sdk_version":    `"current"`, // use as default
+				"optimize":       `False`,
 			}),
 		}})
 }
@@ -260,6 +300,9 @@
 	manifest: "fooManifest.xml",
 	libs: ["barLib"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -278,6 +321,7 @@
 				"certificate": `":foocert"`,
 				"manifest":    `"fooManifest.xml"`,
 				"sdk_version": `"current"`, // use as default
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -290,15 +334,17 @@
 		Filesystem: map[string]string{
 			"res/res.png": "",
 		},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	srcs: ["a.java"],
 	common_srcs: ["b.kt"],
-	certificate: "foocert",
 	manifest: "fooManifest.xml",
 	libs:        ["barLib"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 java_library{
 	name:   "barLib",
@@ -315,10 +361,10 @@
 				"sdk_version":    `"current"`, // use as default
 			}),
 			MakeBazelTarget("android_binary", "foo", AttrNameToString{
-				"deps":             `[":foo_kt"]`,
-				"certificate_name": `"foocert"`,
-				"manifest":         `"fooManifest.xml"`,
-				"sdk_version":      `"current"`, // use as default
+				"deps":        `[":foo_kt"]`,
+				"manifest":    `"fooManifest.xml"`,
+				"sdk_version": `"current"`, // use as default
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -331,14 +377,16 @@
 		Filesystem: map[string]string{
 			"res/res.png": "",
 		},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	srcs: ["a.java", "b.kt"],
-	certificate: ":foocert",
 	manifest: "fooManifest.xml",
 	kotlincflags: ["-flag1", "-flag2"],
 	sdk_version: "current",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -357,9 +405,9 @@
 			}),
 			MakeBazelTarget("android_binary", "foo", AttrNameToString{
 				"deps":        `[":foo_kt"]`,
-				"certificate": `":foocert"`,
 				"manifest":    `"fooManifest.xml"`,
 				"sdk_version": `"current"`,
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -370,13 +418,16 @@
 		ModuleTypeUnderTest:        "android_app",
 		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
 		Filesystem:                 map[string]string{},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	sdk_version: "current",
 	min_sdk_version: "24",
 	max_sdk_version: "30",
 	target_sdk_version: "29",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -389,6 +440,7 @@
         "targetSdkVersion": "29",
     }`,
 				"sdk_version": `"current"`,
+				"optimize":    `False`,
 			}),
 		}})
 }
@@ -399,10 +451,13 @@
 		ModuleTypeUnderTest:        "android_app",
 		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
 		Filesystem:                 map[string]string{},
-		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+		Blueprint: `
 android_app {
 	name: "foo",
 	sdk_version: "30",
+	optimize: {
+		enabled: false,
+	},
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -414,6 +469,7 @@
         "targetSdkVersion": "30",
     }`,
 				"sdk_version": `"30"`,
+				"optimize":    `False`,
 			}),
 		}})
 }
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 02ed57a..e50c710 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -5241,3 +5241,41 @@
 	}
 	runCcLibraryTestCase(t, tc)
 }
+
+// `foo_device` and `bar_host` can depend on .proto files of a specific dir,
+// the dynamically generated proto_library should not have any target_compatible_with
+func TestProtoLibraryForIncludeDirsIsOsAgnostic(t *testing.T) {
+	tc := Bp2buildTestCase{
+		Description:                "proto_library generated for proto.include_dirs is compatible for all axes",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite") + `
+cc_library {
+	name: "foo_device",
+	device_supported: true, // this is the default behavior, but added explicitly here for illustration
+	host_supported: false,
+	proto: {include_dirs: ["dir"]},
+}
+cc_library {
+	name: "bar_host",
+	device_supported: false,
+	host_supported: true,
+	srcs: ["bar.proto"],
+	proto: {include_dirs: ["dir"]},
+}
+`,
+		Filesystem: map[string]string{
+			"dir/Android.bp": "",
+			"dir/dir.proto":  "",
+		},
+		Dir: "dir", // check for the generated proto_library
+		ExpectedBazelTargets: []string{
+			MakeBazelTargetNoRestrictions("proto_library", "dir.include_dir_bp2build_generated_proto", AttrNameToString{
+				"srcs":                `["dir.proto"]`,
+				"strip_import_prefix": `""`,
+				"tags":                `["manual"]`,
+			}),
+		},
+	}
+	runCcLibraryTestCase(t, tc)
+}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 7791419..35a1400 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -48,7 +48,11 @@
 	}
 	files = append(files, newFile("apex_toolchain", "constants.bzl", apexToolchainVars))
 
-	files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.Serialize().ConvertedModules, "\n")))
+	if buf, err := json.MarshalIndent(metrics.convertedModuleWithType, "", "  "); err != nil {
+		return []BazelFile{}, err
+	} else {
+		files = append(files, newFile("metrics", "converted_modules.json", string(buf)))
+	}
 
 	convertedModulePathMap, err := json.MarshalIndent(metrics.convertedModulePathMap, "", "\t")
 	if err != nil {
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index cbffaa0..89dd38e 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -134,7 +134,7 @@
 		},
 		{
 			dir:      "metrics",
-			basename: "converted_modules.txt",
+			basename: "converted_modules.json",
 		},
 		{
 			dir:      "metrics",
diff --git a/bp2build/metrics.go b/bp2build/metrics.go
index 00f21c8..20002c6 100644
--- a/bp2build/metrics.go
+++ b/bp2build/metrics.go
@@ -9,11 +9,17 @@
 	"android/soong/android"
 	"android/soong/shared"
 	"android/soong/ui/metrics/bp2build_metrics_proto"
+
 	"google.golang.org/protobuf/proto"
 
 	"github.com/google/blueprint"
 )
 
+type moduleInfo struct {
+	Name string `json:"name"`
+	Type string `json:"type"`
+}
+
 // CodegenMetrics represents information about the Blueprint-to-BUILD
 // conversion process.
 // Use CreateCodegenMetrics() to get a properly initialized instance
@@ -30,6 +36,9 @@
 	// Map of converted modules and paths to call
 	// NOTE: NOT in the .proto
 	convertedModulePathMap map[string]string
+
+	// Name and type of converted modules
+	convertedModuleWithType []moduleInfo
 }
 
 func CreateCodegenMetrics() CodegenMetrics {
@@ -191,6 +200,10 @@
 	// Undo prebuilt_ module name prefix modifications
 	moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name())
 	metrics.serialized.ConvertedModules = append(metrics.serialized.ConvertedModules, moduleName)
+	metrics.convertedModuleWithType = append(metrics.convertedModuleWithType, moduleInfo{
+		moduleName,
+		moduleType,
+	})
 	metrics.convertedModulePathMap[moduleName] = "//" + dir
 	metrics.serialized.ConvertedModuleTypeCount[moduleType] += 1
 	metrics.serialized.TotalModuleTypeCount[moduleType] += 1
diff --git a/bp2build/rust_binary_conversion_test.go b/bp2build/rust_binary_conversion_test.go
index 3364401..a5abbdb 100644
--- a/bp2build/rust_binary_conversion_test.go
+++ b/bp2build/rust_binary_conversion_test.go
@@ -1,3 +1,17 @@
+// Copyright 2023 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 (
diff --git a/bp2build/rust_library_conversion_test.go b/bp2build/rust_library_conversion_test.go
index b860b76..0bc80df 100644
--- a/bp2build/rust_library_conversion_test.go
+++ b/bp2build/rust_library_conversion_test.go
@@ -1,3 +1,17 @@
+// Copyright 2023 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 (
diff --git a/bp2build/rust_proc_macro_conversion_test.go b/bp2build/rust_proc_macro_conversion_test.go
index 82e080d..7df37ec 100644
--- a/bp2build/rust_proc_macro_conversion_test.go
+++ b/bp2build/rust_proc_macro_conversion_test.go
@@ -1,3 +1,17 @@
+// Copyright 2023 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 (
@@ -17,7 +31,7 @@
 }
 
 func TestRustProcMacroLibrary(t *testing.T) {
-	runRustLibraryTestCase(t, Bp2buildTestCase{
+	rustRustProcMacroTestCase(t, Bp2buildTestCase{
 		Dir:       "external/rust/crates/foo",
 		Blueprint: "",
 		Filesystem: map[string]string{
diff --git a/bp2build/rust_protobuf_conversion_test.go b/bp2build/rust_protobuf_conversion_test.go
index a779c36..cf256aa 100644
--- a/bp2build/rust_protobuf_conversion_test.go
+++ b/bp2build/rust_protobuf_conversion_test.go
@@ -1,3 +1,17 @@
+// Copyright 2023 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 (
diff --git a/cc/config/OWNERS b/cc/config/OWNERS
index 580f215..c78b6d5 100644
--- a/cc/config/OWNERS
+++ b/cc/config/OWNERS
@@ -1,3 +1,3 @@
 per-file vndk.go = smoreland@google.com, victoryang@google.com
-per-file clang.go,global.go,tidy.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
+per-file clang.go,global.go,tidy.go = appujee@google.com, pirama@google.com, srhines@google.com, yabinc@google.com, yikong@google.com, zijunzhao@google.com
 
diff --git a/cc/config/global.go b/cc/config/global.go
index 23a05be..34e0aa7 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -140,6 +140,9 @@
 		"-Werror=format-security",
 		"-nostdlibinc",
 
+		// Enable MLGO for register allocation.
+		"-mllvm -regalloc-enable-advisor=release",
+
 		// Emit additional debug info for AutoFDO
 		"-fdebug-info-for-profiling",
 	}
@@ -167,6 +170,8 @@
 		"-Wl,--exclude-libs,libgcc_stripped.a",
 		"-Wl,--exclude-libs,libunwind_llvm.a",
 		"-Wl,--exclude-libs,libunwind.a",
+		// Enable MLGO for register allocation.
+		"-Wl,-mllvm,-regalloc-enable-advisor=release",
 	}
 
 	deviceGlobalLldflags = append(deviceGlobalLdflags, commonGlobalLldflags...)
@@ -251,9 +256,6 @@
 	noOverrideExternalGlobalCflags = []string{
 		// http://b/191699019
 		"-Wno-format-insufficient-args",
-		// http://b/296422292
-		// Usually signals a mistake and should be a hard error.
-		"-Wno-sizeof-array-div",
 		// http://b/296321145
 		// Indicates potential memory or stack corruption, so should be changed
 		// to a hard error. Currently triggered by some vendor code.
@@ -320,7 +322,7 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r498229"
+	ClangDefaultVersion      = "clang-r498229b"
 	ClangDefaultShortVersion = "17"
 
 	// Directories with warnings from Android.bp files.
diff --git a/cc/lto.go b/cc/lto.go
index 820c1f0..df9ca0a 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -162,7 +162,7 @@
 }
 
 func GlobalThinLTO(ctx android.BaseModuleContext) bool {
-	return ctx.Config().IsEnvTrue("GLOBAL_THINLTO")
+	return !ctx.Config().IsEnvFalse("GLOBAL_THINLTO")
 }
 
 // Propagate lto requirements down from binaries
diff --git a/cc/test.go b/cc/test.go
index c643862..ae62128 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -395,7 +395,7 @@
 
 	useVendor := ctx.inVendor() || ctx.useVndk()
 	testInstallBase := getTestInstallBase(useVendor)
-	configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx))
+	configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx), ctx.Device())
 
 	test.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
 		TestConfigProp:         test.Properties.Test_config,
@@ -435,22 +435,24 @@
 	return testInstallBase
 }
 
-func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBinaryProperties, isolated bool) []tradefed.Config {
+func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBinaryProperties, isolated bool, device bool) []tradefed.Config {
 	var configs []tradefed.Config
 
 	for _, module := range properties.Test_mainline_modules {
 		configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
 	}
-	if Bool(properties.Require_root) {
-		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
-	} else {
-		var options []tradefed.Option
-		options = append(options, tradefed.Option{Name: "force-root", Value: "false"})
-		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
-	}
-	if Bool(properties.Disable_framework) {
-		var options []tradefed.Option
-		configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options})
+	if device {
+		if Bool(properties.Require_root) {
+			configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
+		} else {
+			var options []tradefed.Option
+			options = append(options, tradefed.Option{Name: "force-root", Value: "false"})
+			configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
+		}
+		if Bool(properties.Disable_framework) {
+			var options []tradefed.Option
+			configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options})
+		}
 	}
 	if isolated {
 		configs = append(configs, tradefed.Option{Name: "not-shardable", Value: "true"})
@@ -760,7 +762,7 @@
 				p.Auto_gen_config,
 				p.Test_options.Test_suite_tag,
 				p.Test_config_template,
-				getTradefedConfigOptions(ctx, p, gtestIsolated),
+				getTradefedConfigOptions(ctx, p, gtestIsolated, true),
 				&testInstallBase,
 			)
 			testBinaryAttrs.TestConfigAttributes = testConfigAttributes
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 8e3f278..d1c2f13 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -912,7 +912,7 @@
 	Out []string
 }
 
-type bazelGenruleAttributes struct {
+type BazelGenruleAttributes struct {
 	Srcs  bazel.LabelListAttribute
 	Outs  []string
 	Tools bazel.LabelListAttribute
@@ -1036,7 +1036,7 @@
 				break
 			}
 		}
-		attrs := &bazelGenruleAttributes{
+		attrs := &BazelGenruleAttributes{
 			Srcs:  srcs,
 			Outs:  outs,
 			Cmd:   cmdProp,
diff --git a/java/app.go b/java/app.go
index dadae48..d71cd77 100755
--- a/java/app.go
+++ b/java/app.go
@@ -29,6 +29,7 @@
 	"android/soong/bazel"
 	"android/soong/cc"
 	"android/soong/dexpreopt"
+	"android/soong/genrule"
 	"android/soong/tradefed"
 )
 
@@ -1614,6 +1615,8 @@
 	Certificate      bazel.LabelAttribute
 	Certificate_name bazel.StringAttribute
 	Manifest_values  *manifestValueAttribute
+	Optimize         *bool
+	Proguard_specs   bazel.LabelListAttribute
 }
 
 // ConvertWithBp2build is used to convert android_app to Bazel.
@@ -1665,6 +1668,41 @@
 		Manifest_values:  manifestValues,
 	}
 
+	if !BoolDefault(a.dexProperties.Optimize.Enabled, true) {
+		appAttrs.Optimize = proptools.BoolPtr(false)
+	} else {
+		handCraftedFlags := ""
+		if Bool(a.dexProperties.Optimize.Ignore_warnings) {
+			handCraftedFlags += "-ignorewarning "
+		}
+		if !Bool(a.dexProperties.Optimize.Shrink) {
+			handCraftedFlags += "-dontshrink "
+		}
+		if !Bool(a.dexProperties.Optimize.Optimize) {
+			handCraftedFlags += "-dontoptimize "
+		}
+		if !Bool(a.dexProperties.Optimize.Obfuscate) {
+			handCraftedFlags += "-dontobfuscate "
+		}
+		appAttrs.Proguard_specs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files))
+		if handCraftedFlags != "" {
+			generatedFlagFileRuleName := a.Name() + "_proguard_flags"
+			ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
+				Rule_class: "genrule",
+			}, android.CommonAttributes{
+				Name:     generatedFlagFileRuleName,
+				SkipData: proptools.BoolPtr(true),
+			}, &genrule.BazelGenruleAttributes{
+				Outs: []string{a.Name() + "_proguard.flags"},
+				Cmd: bazel.StringAttribute{
+					Value: proptools.StringPtr("echo " + handCraftedFlags + "> $(OUTS)"),
+				},
+			})
+			appAttrs.Proguard_specs.Add(bazel.MakeLabelAttribute(":" + generatedFlagFileRuleName))
+		}
+
+	}
+
 	props := bazel.BazelTargetModuleProperties{
 		Rule_class:        "android_binary",
 		Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
diff --git a/java/java.go b/java/java.go
index 6c448a2..521aef3 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1735,7 +1735,6 @@
 
 	cmd.Flag("--color").
 		Flag("--quiet").
-		Flag("--format=v2").
 		Flag("--include-annotations").
 		// The flag makes nullability issues as warnings rather than errors by replacing
 		// @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull,
@@ -1747,14 +1746,13 @@
 		FlagWithArg("--hide ", "InvalidNullabilityOverride").
 		FlagWithArg("--hide ", "ChangedDefault")
 
-	// Force metalava to ignore classes on the classpath when an API file contains missing classes.
-	// See b/285140653 for more information.
+	// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
+	// classes on the classpath when an API file contains missing classes. However, as this command
+	// does not specify `--classpath` this is not needed for that. However, this is also used as a
+	// signal to the special metalava code for generating stubs from text files that it needs to add
+	// some additional items into the API (e.g. default constructors).
 	cmd.FlagWithArg("--api-class-resolution ", "api")
 
-	// Force metalava to sort overloaded methods by their order in the source code.
-	// See b/285312164 for more information.
-	cmd.FlagWithArg("--api-overloaded-method-order ", "source")
-
 	return cmd
 }
 
@@ -1916,7 +1914,7 @@
 		FlagWithArg("-C ", stubsDir.String()).
 		FlagWithArg("-D ", stubsDir.String())
 
-	rule.Build("metalava", "metalava merged")
+	rule.Build("metalava", "metalava merged text")
 
 	if depApiSrcsStubsJar == nil {
 		var flags javaBuilderFlags
diff --git a/python/python.go b/python/python.go
index 8b31c6c..7d77ca7 100644
--- a/python/python.go
+++ b/python/python.go
@@ -462,8 +462,7 @@
 
 	// generate the zipfile of all source and data files
 	p.srcsZip = p.createSrcsZip(ctx, pkgPath)
-	// TODO(b/278602456): precompilation temporarily disabled for python3.11 upgrade
-	p.precompiledSrcsZip = p.srcsZip //p.precompileSrcs(ctx)
+	p.precompiledSrcsZip = p.precompileSrcs(ctx)
 }
 
 func isValidPythonPath(path string) error {
diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh
index 9801a8e..9de9b97 100755
--- a/tests/sbom_test.sh
+++ b/tests/sbom_test.sh
@@ -85,46 +85,7 @@
   lz4=$out_dir/host/linux-x86/bin/lz4
 
   declare -A diff_excludes
-  diff_excludes[vendor]="\
-    -I /vendor/lib64/libkeystore2_crypto.so \
-    -I /vendor/lib64/libvsock_utils.so"
-  diff_excludes[system]="\
-    -I /system/bin/assemble_cvd \
-    -I /system/bin/console_forwarder \
-    -I /system/bin/kernel_log_monitor \
-    -I /system/bin/logcat_receiver \
-    -I /system/bin/mkenvimage_slim \
-    -I /system/bin/run_cvd \
-    -I /system/bin/simg2img \
-    -I /system/bin/log_tee \
-    -I /system/lib64/android.hardware.confirmationui@1.0.so \
-    -I /system/lib64/android.hardware.confirmationui-V1-ndk.so \
-    -I /system/lib64/android.hardware.keymaster@4.1.so \
-    -I /system/lib64/android.hardware.security.rkp-V3-ndk.so \
-    -I /system/lib64/android.hardware.security.sharedsecret-V1-ndk.so \
-    -I /system/lib64/android.security.compat-ndk.so \
-    -I /system/lib64/libcuttlefish_allocd_utils.so \
-    -I /system/lib64/libcuttlefish_device_config_proto.so \
-    -I /system/lib64/libcuttlefish_device_config.so \
-    -I /system/lib64/libcuttlefish_fs.so \
-    -I /system/lib64/libcuttlefish_kernel_log_monitor_utils.so \
-    -I /system/lib64/libcuttlefish_utils.so \
-    -I /system/lib64/libfruit.so \
-    -I /system/lib64/libgflags.so \
-    -I /system/lib64/libkeymaster4_1support.so \
-    -I /system/lib64/libkeymaster4support.so \
-    -I /system/lib64/libkeymint.so \
-    -I /system/lib64/libkeystore2_aaid.so \
-    -I /system/lib64/libkeystore2_apc_compat.so \
-    -I /system/lib64/libkeystore2_crypto.so \
-    -I /system/lib64/libkeystore-attestation-application-id.so \
-    -I /system/lib64/libkm_compat_service.so \
-    -I /system/lib64/libkm_compat.so \
-    -I /system/lib64/vndk-29 \
-    -I /system/lib64/vndk-sp-29 \
-    -I /system/lib/vndk-29 \
-    -I /system/lib/vndk-sp-29 \
-    -I /system/usr/icu"
+  diff_excludes[system]="-I /system/bin/hwservicemanager"
 
   # Example output of dump.erofs is as below, and the data used in the test start
   # at line 11. Column 1 is inode id, column 2 is inode type and column 3 is name.