Merge "Set -fno-emulated-tls for riscv64"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 31368b2..10c3d09 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -187,6 +187,7 @@
 		"frameworks/base/services/tests/servicestests/aidl":  Bp2BuildDefaultTrue,
 		"frameworks/base/startop/apps/test":                  Bp2BuildDefaultTrue,
 		"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
+		"frameworks/base/tools/streaming_proto":              Bp2BuildDefaultTrueRecursively,
 		"frameworks/base/tools/aapt2":                        Bp2BuildDefaultTrue,
 		"frameworks/native/libs/adbd_auth":                   Bp2BuildDefaultTrueRecursively,
 		"frameworks/native/libs/arect":                       Bp2BuildDefaultTrueRecursively,
@@ -397,8 +398,12 @@
 		"com.android.neuralnetworks.certificate",
 		"com.android.neuralnetworks.key",
 		"flatbuffer_headers",
+		"framework-cppstream-protos",
+		"framework-javastream-protos",
+		"framework-connectivity-protos",
 		"gemmlowp_headers",
 		"gl_headers",
+		"ipconnectivity-proto-src",
 		"libaidlcommonsupport",
 		"libandroid_runtime_lazy",
 		"libandroid_runtime_vm_headers",
@@ -474,6 +479,7 @@
 		"philox_random",
 		"philox_random_headers",
 		"server_configurable_flags",
+		"service-permission-streaming-proto-sources",
 		"statslog_neuralnetworks.cpp",
 		"statslog_neuralnetworks.h",
 		"tensorflow_headers",
@@ -602,8 +608,6 @@
 		"libEGL_getProcAddress",
 		"libEGL_blobCache",
 
-		"protoc-gen-cppstream",
-
 		"mediaswcodec",
 		"libmedia_headers",
 		"libmedia_codecserviceregistrant",
@@ -1280,6 +1284,10 @@
 		"libapplypatch",
 		"libapplypatch_modes",
 		"applypatch",
+
+		// TODO(b/254476335): disable the following due to this bug
+		"libapexinfo",
+		"libapexinfo_tests",
 	}
 
 	Bp2buildCcLibraryStaticOnlyList = []string{}
@@ -1330,7 +1338,6 @@
 		"prebuilt_currysrc_org.eclipse",
 
 		// TODO(b/247782695 and/or b/242847534) Fix mixed build between unconverted gensrcs and converted filegroup
-		"libstats_atom_enum_protos",
 		"data_stall_event_proto",
 		"device_policy_proto",
 		"dns_resolver_proto",
@@ -1341,7 +1348,6 @@
 		"style_proto",
 		"tethering_proto",
 		"text_classifier_proto",
-		"libstats_atom_message_protos",
 	}
 
 	ProdMixedBuildsEnabledList = []string{
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 9c50098..b2ea22f 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -534,3 +534,55 @@
 	}
 	return outs
 }
+
+// BazelStringOrLabelFromProp splits a Soong module property that can be
+// either a string literal, path (with android:path tag) or a module reference
+// into separate bazel string or label attributes. Bazel treats string and label
+// attributes as distinct types, so this function categorizes a string property
+// into either one of them.
+//
+// e.g. apex.private_key = "foo.pem" can either refer to:
+//
+// 1. "foo.pem" in the current directory -> file target
+// 2. "foo.pem" module -> rule target
+// 3. "foo.pem" file in a different directory, prefixed by a product variable handled
+// in a bazel macro. -> string literal
+//
+// For the first two cases, they are defined using the label attribute. For the third case,
+// it's defined with the string attribute.
+func BazelStringOrLabelFromProp(
+	ctx TopDownMutatorContext,
+	propToDistinguish *string) (bazel.LabelAttribute, bazel.StringAttribute) {
+
+	var labelAttr bazel.LabelAttribute
+	var strAttr bazel.StringAttribute
+
+	if propToDistinguish == nil {
+		// nil pointer
+		return labelAttr, strAttr
+	}
+
+	prop := String(propToDistinguish)
+	if SrcIsModule(prop) != "" {
+		// If it's a module (SrcIsModule will return the module name), set the
+		// resolved label to the label attribute.
+		labelAttr.SetValue(BazelLabelForModuleDepSingle(ctx, prop))
+	} else {
+		// Not a module name. This could be a string literal or a file target in
+		// the current dir. Check if the path exists:
+		path := ExistentPathForSource(ctx, ctx.ModuleDir(), prop)
+
+		if path.Valid() && parentDir(path.String()) == ctx.ModuleDir() {
+			// If it exists and the path is relative to the current dir, resolve the bazel label
+			// for the _file target_ and set it to the label attribute.
+			//
+			// Resolution is necessary because this could be a file in a subpackage.
+			labelAttr.SetValue(BazelLabelForModuleSrcSingle(ctx, prop))
+		} else {
+			// Otherwise, treat it as a string literal and assign to the string attribute.
+			strAttr.Value = propToDistinguish
+		}
+	}
+
+	return labelAttr, strAttr
+}
diff --git a/apex/apex.go b/apex/apex.go
index edba1f7..88a057f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2665,12 +2665,13 @@
 
 		// Certificate
 		if overridableProperties.Certificate == nil {
-			// delegated to the rule attr default
-			attrs.Certificate = nil
+			// If overridableProperties.Certificate is nil, clear this out as
+			// well with zeroed structs, so the override_apex does not use the
+			// base apex's certificate.
+			attrs.Certificate = bazel.LabelAttribute{}
+			attrs.Certificate_name = bazel.StringAttribute{}
 		} else {
-			certificateName, certificate := java.ParseCertificateToAttribute(ctx, overridableProperties.Certificate)
-			attrs.Certificate_name = certificateName
-			attrs.Certificate = certificate
+			attrs.Certificate, attrs.Certificate_name = android.BazelStringOrLabelFromProp(ctx, overridableProperties.Certificate)
 		}
 
 		// Prebuilts
@@ -3346,8 +3347,8 @@
 	Android_manifest      bazel.LabelAttribute
 	File_contexts         bazel.LabelAttribute
 	Key                   bazel.LabelAttribute
-	Certificate           *bazel.Label // used when the certificate prop is a module
-	Certificate_name      *string      // used when the certificate prop is a string
+	Certificate           bazel.LabelAttribute  // used when the certificate prop is a module
+	Certificate_name      bazel.StringAttribute // used when the certificate prop is a string
 	Min_sdk_version       *string
 	Updatable             bazel.BoolAttribute
 	Installable           bazel.BoolAttribute
@@ -3409,7 +3410,8 @@
 		keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
 	}
 
-	certificateName, certificate := java.ParseCertificateToAttribute(ctx, a.overridableProperties.Certificate)
+	// Certificate
+	certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableProperties.Certificate)
 
 	nativeSharedLibs := &convertedNativeSharedLibs{
 		Native_shared_libs_32: bazel.LabelListAttribute{},
diff --git a/apex/builder.go b/apex/builder.go
index ad8075b..e4c1673 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -922,10 +922,16 @@
 				installedSymlinks = append(installedSymlinks,
 					ctx.InstallAbsoluteSymlink(installDir, fi.stem(), pathOnDevice))
 			} else {
-				target := ctx.InstallFile(installDir, fi.stem(), fi.builtFile)
-				for _, sym := range fi.symlinks {
-					installedSymlinks = append(installedSymlinks,
-						ctx.InstallSymlink(installDir, sym, target))
+				if fi.class == appSet {
+					as := fi.module.(*java.AndroidAppSet)
+					ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk",
+						as.OutputFile(), as.PackedAdditionalOutputs())
+				} else {
+					target := ctx.InstallFile(installDir, fi.stem(), fi.builtFile)
+					for _, sym := range fi.symlinks {
+						installedSymlinks = append(installedSymlinks,
+							ctx.InstallSymlink(installDir, sym, target))
+					}
 				}
 			}
 		}
diff --git a/apex/key.go b/apex/key.go
index 2b09f1d..0a7e80f 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -201,10 +201,10 @@
 
 type bazelApexKeyAttributes struct {
 	Public_key      bazel.LabelAttribute
-	Public_key_name bazel.LabelAttribute
+	Public_key_name bazel.StringAttribute
 
 	Private_key      bazel.LabelAttribute
-	Private_key_name bazel.LabelAttribute
+	Private_key_name bazel.StringAttribute
 }
 
 // ConvertWithBp2build performs conversion apexKey for bp2build
@@ -213,27 +213,11 @@
 }
 
 func apexKeyBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexKey) {
-	var privateKeyLabelAttribute bazel.LabelAttribute
-	var privateKeyNameAttribute bazel.LabelAttribute
-	if module.properties.Private_key != nil {
-		m := String(module.properties.Private_key)
-		if android.SrcIsModule(m) == "" {
-			privateKeyNameAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Private_key))
-		} else {
-			privateKeyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.properties.Private_key))
-		}
-	}
+	privateKeyLabelAttribute, privateKeyNameAttribute :=
+		android.BazelStringOrLabelFromProp(ctx, module.properties.Private_key)
 
-	var publicKeyLabelAttribute bazel.LabelAttribute
-	var publicKeyNameAttribute bazel.LabelAttribute
-	if module.properties.Public_key != nil {
-		m := String(module.properties.Public_key)
-		if android.SrcIsModule(m) == "" {
-			publicKeyNameAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *module.properties.Public_key))
-		} else {
-			publicKeyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.properties.Public_key))
-		}
-	}
+	publicKeyLabelAttribute, publicKeyNameAttribute :=
+		android.BazelStringOrLabelFromProp(ctx, module.properties.Public_key)
 
 	attrs := &bazelApexKeyAttributes{
 		Private_key:      privateKeyLabelAttribute,
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index e112be3..2b35521 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -27,6 +27,7 @@
 }
 
 func registerAndroidAppModuleTypes(ctx android.RegistrationContext) {
+	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 }
 
 func TestMinimalAndroidApp(t *testing.T) {
@@ -76,6 +77,7 @@
         manifest: "manifest/AndroidManifest.xml",
         static_libs: ["static_lib_dep"],
         java_version: "7",
+        certificate: "foocert",
 }
 `,
 		ExpectedBazelTargets: []string{
@@ -86,9 +88,10 @@
         "resa/res.png",
         "resb/res.png",
     ]`,
-				"custom_package": `"com.google"`,
-				"deps":           `[":static_lib_dep"]`,
-				"javacopts":      `["-source 1.7 -target 1.7"]`,
+				"custom_package":   `"com.google"`,
+				"deps":             `[":static_lib_dep"]`,
+				"javacopts":        `["-source 1.7 -target 1.7"]`,
+				"certificate_name": `"foocert"`,
 			}),
 		}})
 }
@@ -130,3 +133,70 @@
 			}),
 		}})
 }
+
+func TestAndroidAppCertIsModule(t *testing.T) {
+	runAndroidAppTestCase(t, Bp2buildTestCase{
+		Description:                "Android app - cert is module",
+		ModuleTypeUnderTest:        "android_app",
+		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
+		Filesystem:                 map[string]string{},
+		Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+android_app {
+        name: "TestApp",
+        certificate: ":foocert",
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("android_binary", "TestApp", AttrNameToString{
+				"certificate":    `":foocert"`,
+				"manifest":       `"AndroidManifest.xml"`,
+				"resource_files": `[]`,
+			}),
+		}})
+}
+
+func TestAndroidAppCertIsSrcFile(t *testing.T) {
+	runAndroidAppTestCase(t, Bp2buildTestCase{
+		Description:                "Android app - cert is src file",
+		ModuleTypeUnderTest:        "android_app",
+		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
+		Filesystem: map[string]string{
+			"foocert": "",
+		},
+		Blueprint: `
+android_app {
+        name: "TestApp",
+        certificate: "foocert",
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("android_binary", "TestApp", AttrNameToString{
+				"certificate":    `"foocert"`,
+				"manifest":       `"AndroidManifest.xml"`,
+				"resource_files": `[]`,
+			}),
+		}})
+}
+
+func TestAndroidAppCertIsNotSrcOrModule(t *testing.T) {
+	runAndroidAppTestCase(t, Bp2buildTestCase{
+		Description:                "Android app - cert is not src or module",
+		ModuleTypeUnderTest:        "android_app",
+		ModuleTypeUnderTestFactory: java.AndroidAppFactory,
+		Filesystem:                 map[string]string{
+			// deliberate empty
+		},
+		Blueprint: `
+android_app {
+        name: "TestApp",
+        certificate: "foocert",
+}
+`,
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("android_binary", "TestApp", AttrNameToString{
+				"certificate_name": `"foocert"`,
+				"manifest":         `"AndroidManifest.xml"`,
+				"resource_files":   `[]`,
+			}),
+		}})
+}
diff --git a/bp2build/apex_key_conversion_test.go b/bp2build/apex_key_conversion_test.go
index 79b1d89..f9a68c9 100644
--- a/bp2build/apex_key_conversion_test.go
+++ b/bp2build/apex_key_conversion_test.go
@@ -30,12 +30,37 @@
 	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
 }
 
-func TestApexKeySimple_KeysAreSrcFiles(t *testing.T) {
+func TestApexKeySimple_KeysAreSrcFilesInSameDir(t *testing.T) {
 	runApexKeyTestCase(t, Bp2buildTestCase{
-		Description:                "apex key - keys are src files, use key_name attributes",
+		Description:                "apex key - keys are src files, use key attributes",
 		ModuleTypeUnderTest:        "apex_key",
 		ModuleTypeUnderTestFactory: apex.ApexKeyFactory,
-		Filesystem:                 map[string]string{},
+		Filesystem: map[string]string{
+			"com.android.apogee.avbpubkey": "",
+			"com.android.apogee.pem":       "",
+		},
+		Blueprint: `
+apex_key {
+        name: "com.android.apogee.key",
+        public_key: "com.android.apogee.avbpubkey",
+        private_key: "com.android.apogee.pem",
+}
+`,
+		ExpectedBazelTargets: []string{MakeBazelTargetNoRestrictions("apex_key", "com.android.apogee.key", AttrNameToString{
+			"private_key": `"com.android.apogee.pem"`,
+			"public_key":  `"com.android.apogee.avbpubkey"`,
+		}),
+		}})
+}
+
+func TestApexKeySimple_KeysAreSrcFilesNotInDir(t *testing.T) {
+	runApexKeyTestCase(t, Bp2buildTestCase{
+		Description:                "apex key - keys are not src or module, use key_name attributes",
+		ModuleTypeUnderTest:        "apex_key",
+		ModuleTypeUnderTestFactory: apex.ApexKeyFactory,
+		Filesystem:                 map[string]string{
+			// deliberately left empty
+		},
 		Blueprint: `
 apex_key {
         name: "com.android.apogee.key",
diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go
index dd217c3..47006ac 100644
--- a/bp2build/cc_prebuilt_library_conversion_test.go
+++ b/bp2build/cc_prebuilt_library_conversion_test.go
@@ -36,10 +36,10 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
-				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
 				}),
 			},
@@ -66,14 +66,14 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
         "//conditions:default": None,
     })`,
 				}),
-				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
@@ -104,13 +104,13 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library":         `"libf.so"`,
 					"export_includes":        `["testdir/1/"]`,
 					"export_system_includes": `["testdir/2/"]`,
 				}),
 				// TODO(b/229374533): When fixed, update this test
-				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
 				}),
 			},
@@ -185,10 +185,10 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
-				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libg.so"`,
 				}),
 			},
@@ -215,7 +215,7 @@
 //	bazel_module: { bp2build_available: true },
 //}`,
 //			expectedBazelTargets: []string{
-//				makeBazelTarget("prebuilt_library_shared", "libtest", attrNameToString{
+//				makeBazelTarget("cc_prebuilt_library_shared", "libtest", attrNameToString{
 //					"shared_library": `"libf.so"`,
 //				}),
 //			},
@@ -242,7 +242,7 @@
 //	bazel_module: { bp2build_available: true },
 //}`,
 //			expectedBazelTargets: []string{
-//				makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
+//				makeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
 //					"static_library": `"libf.so"`,
 //				}),
 //			},
diff --git a/bp2build/cc_prebuilt_library_shared_test.go b/bp2build/cc_prebuilt_library_shared_test.go
index 541ce5e..58c0a70 100644
--- a/bp2build/cc_prebuilt_library_shared_test.go
+++ b/bp2build/cc_prebuilt_library_shared_test.go
@@ -23,7 +23,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
 				}),
 			},
@@ -50,7 +50,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_shared", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
diff --git a/bp2build/cc_prebuilt_library_static_test.go b/bp2build/cc_prebuilt_library_static_test.go
index 69a1b5e..6116b00 100644
--- a/bp2build/cc_prebuilt_library_static_test.go
+++ b/bp2build/cc_prebuilt_library_static_test.go
@@ -36,7 +36,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_static", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
 			},
@@ -63,7 +63,7 @@
 	bazel_module: { bp2build_available: true },
 }`,
 			ExpectedBazelTargets: []string{
-				MakeBazelTarget("prebuilt_library_static", "libtest", AttrNameToString{
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{
 					"static_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
diff --git a/bp2build/genrule_conversion_test.go b/bp2build/genrule_conversion_test.go
index 160395b..3490881 100644
--- a/bp2build/genrule_conversion_test.go
+++ b/bp2build/genrule_conversion_test.go
@@ -15,12 +15,13 @@
 package bp2build
 
 import (
+	"fmt"
+	"testing"
+
 	"android/soong/android"
 	"android/soong/cc"
 	"android/soong/genrule"
 	"android/soong/java"
-	"fmt"
-	"testing"
 )
 
 func registerGenruleModuleTypes(ctx android.RegistrationContext) {
@@ -643,3 +644,50 @@
 		})
 	}
 }
+
+func TestCcGenruleArchAndExcludeSrcs(t *testing.T) {
+	name := "cc_genrule with arch"
+	bp := `
+	cc_genrule {
+		name: "foo",
+		srcs: [
+			"foo1.in",
+			"foo2.in",
+		],
+		exclude_srcs: ["foo2.in"],
+		arch: {
+			arm: {
+				srcs: [
+					"foo1_arch.in",
+					"foo2_arch.in",
+				],
+				exclude_srcs: ["foo2_arch.in"],
+			},
+		},
+		cmd: "cat $(in) > $(out)",
+		bazel_module: { bp2build_available: true },
+	}`
+
+	expectedBazelAttrs := AttrNameToString{
+		"srcs": `["foo1.in"] + select({
+        "//build/bazel/platforms/arch:arm": ["foo1_arch.in"],
+        "//conditions:default": [],
+    })`,
+		"cmd":                    `"cat $(SRCS) > $(OUTS)"`,
+		"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+	}
+
+	expectedBazelTargets := []string{
+		MakeBazelTargetNoRestrictions("genrule", "foo", expectedBazelAttrs),
+	}
+
+	t.Run(name, func(t *testing.T) {
+		RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
+			Bp2buildTestCase{
+				ModuleTypeUnderTest:        "cc_genrule",
+				ModuleTypeUnderTestFactory: cc.GenRuleFactory,
+				Blueprint:                  bp,
+				ExpectedBazelTargets:       expectedBazelTargets,
+			})
+	})
+}
diff --git a/cc/config/global.go b/cc/config/global.go
index 4e4d174..f6fcc13 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -150,6 +150,11 @@
 		"-fdebug-info-for-profiling",
 	}
 
+	commonGlobalLldflags = []string{
+		"-fuse-ld=lld",
+		"-Wl,--icf=safe",
+	}
+
 	deviceGlobalCppflags = []string{
 		"-fvisibility-inlines-hidden",
 	}
@@ -167,13 +172,9 @@
 		"-Wl,--exclude-libs,libgcc_stripped.a",
 		"-Wl,--exclude-libs,libunwind_llvm.a",
 		"-Wl,--exclude-libs,libunwind.a",
-		"-Wl,--icf=safe",
 	}
 
-	deviceGlobalLldflags = append(deviceGlobalLdflags,
-		[]string{
-			"-fuse-ld=lld",
-		}...)
+	deviceGlobalLldflags = append(deviceGlobalLdflags, commonGlobalLldflags...)
 
 	hostGlobalCflags = []string{}
 
@@ -181,7 +182,7 @@
 
 	hostGlobalLdflags = []string{}
 
-	hostGlobalLldflags = []string{"-fuse-ld=lld"}
+	hostGlobalLldflags = commonGlobalLldflags
 
 	commonGlobalCppflags = []string{
 		"-Wsign-promo",
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index af49e88..ad205cf 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -58,17 +58,14 @@
 )
 
 func init() {
-	// Many clang-tidy checks like altera-*, llvm-*, modernize-*
-	// are not designed for Android source code or creating too
-	// many (false-positive) warnings. The global default tidy checks
-	// should include only tested groups and exclude known noisy checks.
+	// The global default tidy checks should include clang-tidy
+	// default checks and tested groups, but exclude known noisy checks.
 	// See https://clang.llvm.org/extra/clang-tidy/checks/list.html
 	pctx.VariableFunc("TidyDefaultGlobalChecks", func(ctx android.PackageVarContext) string {
 		if override := ctx.Config().Getenv("DEFAULT_GLOBAL_TIDY_CHECKS"); override != "" {
 			return override
 		}
 		checks := strings.Join([]string{
-			"-*",
 			"android-*",
 			"bugprone-*",
 			"cert-*",
@@ -95,7 +92,7 @@
 			"-misc-non-private-member-variables-in-classes",
 			"-misc-unused-parameters",
 			"-performance-no-int-to-ptr",
-			// the following groups are excluded by -*
+			// the following groups are not in clang-tidy default checks.
 			// -altera-*
 			// -cppcoreguidelines-*
 			// -darwin-*
@@ -109,28 +106,34 @@
 			// -readability-*
 			// -zircon-*
 		}, ",")
-		// clang-analyzer-* checks are too slow to be in the default for WITH_TIDY=1.
-		// nightly builds add CLANG_ANALYZER_CHECKS=1 to run those checks.
+		// clang-analyzer-* checks are slow for large files, but we have TIDY_TIMEOUT to
+		// limit clang-tidy runtime. We allow clang-tidy default clang-analyzer-* checks,
+		// and add it explicitly when CLANG_ANALYZER_CHECKS is set.
 		// The insecureAPI.DeprecatedOrUnsafeBufferHandling warning does not apply to Android.
 		if ctx.Config().IsEnvTrue("CLANG_ANALYZER_CHECKS") {
 			checks += ",clang-analyzer-*,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling"
+		} else {
+			checks += ",-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling"
 		}
 		return checks
 	})
 
-	// There are too many clang-tidy warnings in external and vendor projects.
-	// Enable only some google checks for these projects.
+	// The external and vendor projects do not run clang-tidy unless TIDY_EXTERNAL_VENDOR is set.
+	// We do not add "-*" to the check list to avoid suppressing the check list in .clang-tidy config files.
+	// There are too many clang-tidy warnings in external and vendor projects, so we only
+	// enable some google checks for these projects. Users can add more checks locally with the
+	// "tidy_checks" list in .bp files, or the "Checks" list in .clang-tidy config files.
 	pctx.VariableFunc("TidyExternalVendorChecks", func(ctx android.PackageVarContext) string {
 		if override := ctx.Config().Getenv("DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS"); override != "" {
 			return override
 		}
 		return strings.Join([]string{
-			"-*",
 			"clang-diagnostic-unused-command-line-argument",
 			"google-build-explicit-make-pair",
 			"google-build-namespaces",
 			"google-runtime-operator",
 			"google-upgrade-*",
+			"-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling",
 		}, ",")
 	})
 
@@ -202,11 +205,18 @@
 	return tidyDefault
 }
 
-func NoClangTidyForDir(dir string) bool {
+func neverTidyForDir(dir string) bool {
+	// This function can be extended if tidy needs to be disabled for more directories.
+	return strings.HasPrefix(dir, "external/grpc-grpc")
+}
+
+func NoClangTidyForDir(allowExternalVendor bool, dir string) bool {
+	// Tidy can be disable for a module in dir, if the dir is "neverTidyForDir",
+	// or if it belongs to external|vendor and !allowExternalVendor.
 	// This function depends on TidyChecksForDir, which selects tidyExternalVendor
-	// checks for external/vendor projects. For those projects we disable clang-tidy
-	// by default, unless some modules enable clang-tidy with tidy:true.
-	return TidyChecksForDir(dir) == tidyExternalVendor
+	// checks for external/vendor projects.
+	return neverTidyForDir(dir) ||
+		(!allowExternalVendor && TidyChecksForDir(dir) == tidyExternalVendor)
 }
 
 // Returns a globally disabled tidy checks, overriding locally selected checks.
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 13c94ad..0fbe45c 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -264,7 +264,7 @@
 	}
 
 	// Grab the list of required shared libraries.
-	fuzzBin.sharedLibraries = CollectAllSharedDependencies(ctx)
+	fuzzBin.sharedLibraries, _ = CollectAllSharedDependencies(ctx)
 
 	for _, lib := range fuzzBin.sharedLibraries {
 		fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
@@ -478,9 +478,10 @@
 // VisitDirectDeps is used first to avoid incorrectly using the core libraries (sanitizer
 // runtimes, libc, libdl, etc.) from a dependency. This may cause issues when dependencies
 // have explicit sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
-func CollectAllSharedDependencies(ctx android.ModuleContext) android.Paths {
+func CollectAllSharedDependencies(ctx android.ModuleContext) (android.Paths, []android.Module) {
 	seen := make(map[string]bool)
 	recursed := make(map[string]bool)
+	deps := []android.Module{}
 
 	var sharedLibraries android.Paths
 
@@ -494,6 +495,7 @@
 			return
 		}
 		seen[ctx.OtherModuleName(dep)] = true
+		deps = append(deps, dep)
 		sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, dep, "unstripped"))
 	})
 
@@ -503,6 +505,7 @@
 		}
 		if !seen[ctx.OtherModuleName(child)] {
 			seen[ctx.OtherModuleName(child)] = true
+			deps = append(deps, child)
 			sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, child, "unstripped"))
 		}
 
@@ -513,5 +516,5 @@
 		return true
 	})
 
-	return sharedLibraries
+	return sharedLibraries, deps
 }
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index f25f704..0d16e62 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -40,14 +40,13 @@
 					name: "gen",
 					tool_files: ["tool"],
 					cmd: "$(location tool) $(in) $(out)",
+					out: ["out_arm"],
 					arch: {
 						arm: {
 							srcs: ["foo"],
-							out: ["out_arm"],
 						},
 						arm64: {
 							srcs: ["bar"],
-							out: ["out_arm64"],
 						},
 					},
 				}
@@ -70,7 +69,7 @@
 		t.Errorf(`want arm inputs %v, got %v`, expected, gen.Implicits.Strings())
 	}
 
-	gen = ctx.ModuleForTests("gen", "android_arm64_armv8-a").Output("out_arm64")
+	gen = ctx.ModuleForTests("gen", "android_arm64_armv8-a").Output("out_arm")
 	expected = []string{"bar"}
 	if !reflect.DeepEqual(expected, gen.Implicits.Strings()[:len(expected)]) {
 		t.Errorf(`want arm64 inputs %v, got %v`, expected, gen.Implicits.Strings())
diff --git a/cc/library_stub.go b/cc/library_stub.go
index 2ebb6ef..1283d76 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -26,10 +26,6 @@
 func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory)
 	ctx.RegisterModuleType("cc_api_headers", CcApiHeadersFactory)
-
-	// cc_api_stub_library shares a lot of ndk_library, and this will be refactored later
-	ctx.RegisterModuleType("cc_api_stub_library", CcApiStubLibraryFactory)
-	ctx.RegisterModuleType("cc_api_contribution", CcApiContributionFactory)
 }
 
 // 'cc_api_library' is a module type which is from the exported API surface
@@ -169,136 +165,3 @@
 	// Stub from API surface should be available for any APEX.
 	return true
 }
-
-func CcApiStubLibraryFactory() android.Module {
-	module, decorator := NewLibrary(android.DeviceSupported)
-	apiStubDecorator := &apiStubDecorator{
-		libraryDecorator: decorator,
-	}
-	apiStubDecorator.BuildOnlyShared()
-
-	module.compiler = apiStubDecorator
-	module.linker = apiStubDecorator
-	module.installer = nil
-	module.library = apiStubDecorator
-	module.Properties.HideFromMake = true // TODO: remove
-
-	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
-	module.AddProperties(&module.Properties,
-		&apiStubDecorator.properties,
-		&apiStubDecorator.MutatedProperties,
-		&apiStubDecorator.apiStubLibraryProperties)
-	return module
-}
-
-type apiStubLiraryProperties struct {
-	Imported_includes []string `android:"path"`
-}
-
-type apiStubDecorator struct {
-	*libraryDecorator
-	properties               libraryProperties
-	apiStubLibraryProperties apiStubLiraryProperties
-}
-
-func (compiler *apiStubDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
-	firstVersion := String(compiler.properties.First_version)
-	return ndkLibraryVersions(ctx, android.ApiLevelOrPanic(ctx, firstVersion))
-}
-
-func (decorator *apiStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
-	if decorator.stubsVersion() == "" {
-		decorator.setStubsVersion("current")
-	} // TODO: fix
-	symbolFile := String(decorator.properties.Symbol_file)
-	nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
-		android.ApiLevelOrPanic(ctx, decorator.stubsVersion()),
-		"")
-	return compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
-}
-
-func (decorator *apiStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
-	decorator.reexportDirs(android.PathsForModuleSrc(ctx, decorator.apiStubLibraryProperties.Imported_includes)...)
-	return decorator.libraryDecorator.link(ctx, flags, deps, objects)
-}
-
-func init() {
-	pctx.HostBinToolVariable("gen_api_surface_build_files", "gen_api_surface_build_files")
-}
-
-type CcApiContribution struct {
-	android.ModuleBase
-	properties ccApiContributionProperties
-}
-
-type ccApiContributionProperties struct {
-	Symbol_file        *string `android:"path"`
-	First_version      *string
-	Export_include_dir *string
-}
-
-func CcApiContributionFactory() android.Module {
-	module := &CcApiContribution{}
-	module.AddProperties(&module.properties)
-	android.InitAndroidModule(module)
-	return module
-}
-
-// Do some simple validations
-// Majority of the build rules will be created in the ctx of the api surface this module contributes to
-func (contrib *CcApiContribution) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	if contrib.properties.Symbol_file == nil {
-		ctx.PropertyErrorf("symbol_file", "%v does not have symbol file", ctx.ModuleName())
-	}
-	if contrib.properties.First_version == nil {
-		ctx.PropertyErrorf("first_version", "%v does not have first_version for stub variants", ctx.ModuleName())
-	}
-}
-
-// Path is out/soong/.export/ but will be different in final multi-tree layout
-func outPathApiSurface(ctx android.ModuleContext, myModuleName string, pathComponent string) android.OutputPath {
-	return android.PathForOutput(ctx, ".export", ctx.ModuleName(), myModuleName, pathComponent)
-}
-
-func (contrib *CcApiContribution) CopyFilesWithTag(apiSurfaceContext android.ModuleContext) map[string]android.Paths {
-	// copy map.txt for now
-	// hardlinks cannot be created since nsjail creates a different mountpoint for out/
-	myDir := apiSurfaceContext.OtherModuleDir(contrib)
-	genMapTxt := outPathApiSurface(apiSurfaceContext, contrib.Name(), String(contrib.properties.Symbol_file))
-	apiSurfaceContext.Build(pctx, android.BuildParams{
-		Rule:        android.Cp,
-		Description: "import map.txt file",
-		Input:       android.PathForSource(apiSurfaceContext, myDir, String(contrib.properties.Symbol_file)),
-		Output:      genMapTxt,
-	})
-
-	outputs := make(map[string]android.Paths)
-	outputs["map"] = []android.Path{genMapTxt}
-
-	if contrib.properties.Export_include_dir != nil {
-		includeDir := android.PathForSource(apiSurfaceContext, myDir, String(contrib.properties.Export_include_dir))
-		outputs["export_include_dir"] = []android.Path{includeDir}
-	}
-	return outputs
-}
-
-var _ multitree.ApiContribution = (*CcApiContribution)(nil)
-
-/*
-func (contrib *CcApiContribution) GenerateBuildFiles(apiSurfaceContext android.ModuleContext) android.Paths {
-	genAndroidBp := outPathApiSurface(apiSurfaceContext, contrib.Name(), "Android.bp")
-
-	// generate Android.bp
-	apiSurfaceContext.Build(pctx, android.BuildParams{
-		Rule:        genApiSurfaceBuildFiles,
-		Description: "generate API surface build files",
-		Outputs:     []android.WritablePath{genAndroidBp},
-		Args: map[string]string{
-			"name":          contrib.Name() + "." + apiSurfaceContext.ModuleName(), //e.g. liblog.ndk
-			"symbol_file":   String(contrib.properties.Symbol_file),
-			"first_version": String(contrib.properties.First_version),
-		},
-	})
-	return []android.Path{genAndroidBp}
-}
-*/
diff --git a/cc/library_stub_test.go b/cc/library_stub_test.go
index cd06172..288a34c 100644
--- a/cc/library_stub_test.go
+++ b/cc/library_stub_test.go
@@ -21,94 +21,10 @@
 	"testing"
 
 	"android/soong/android"
-	"android/soong/multitree"
 
 	"github.com/google/blueprint"
 )
 
-func TestCcApiStubLibraryOutputFiles(t *testing.T) {
-	bp := `
-		cc_api_stub_library {
-			name: "foo",
-			symbol_file: "foo.map.txt",
-			first_version: "29",
-		}
-	`
-	result := prepareForCcTest.RunTestWithBp(t, bp)
-	outputs := result.ModuleForTests("foo", "android_arm64_armv8-a_shared").AllOutputs()
-	expected_file_suffixes := []string{".c", "stub.map", ".o", ".so"}
-	for _, expected_file_suffix := range expected_file_suffixes {
-		android.AssertBoolEquals(t, expected_file_suffix+" file not found in output", true, android.SuffixInList(outputs, expected_file_suffix))
-	}
-}
-
-func TestCcApiStubLibraryVariants(t *testing.T) {
-	bp := `
-		cc_api_stub_library {
-			name: "foo",
-			symbol_file: "foo.map.txt",
-			first_version: "29",
-		}
-	`
-	result := prepareForCcTest.RunTestWithBp(t, bp)
-	variants := result.ModuleVariantsForTests("foo")
-	expected_variants := []string{"29", "30", "S", "Tiramisu"} //TODO: make this test deterministic by using fixtures
-	for _, expected_variant := range expected_variants {
-		android.AssertBoolEquals(t, expected_variant+" variant not found in foo", true, android.SubstringInList(variants, expected_variant))
-	}
-}
-
-func TestCcLibraryUsesCcApiStubLibrary(t *testing.T) {
-	bp := `
-		cc_api_stub_library {
-			name: "foo",
-			symbol_file: "foo.map.txt",
-			first_version: "29",
-		}
-		cc_library {
-			name: "foo_user",
-			shared_libs: [
-				"foo#29",
-			],
-		}
-
-	`
-	prepareForCcTest.RunTestWithBp(t, bp)
-}
-
-func TestApiSurfaceOutputs(t *testing.T) {
-	bp := `
-		api_surface {
-			name: "mysdk",
-			contributions: [
-				"foo",
-			],
-		}
-
-		cc_api_contribution {
-			name: "foo",
-			symbol_file: "foo.map.txt",
-			first_version: "29",
-		}
-	`
-	result := android.GroupFixturePreparers(
-		prepareForCcTest,
-		multitree.PrepareForTestWithApiSurface,
-	).RunTestWithBp(t, bp)
-	mysdk := result.ModuleForTests("mysdk", "")
-
-	actual_surface_inputs := mysdk.Rule("phony").BuildParams.Inputs.Strings()
-	expected_file_suffixes := []string{"mysdk/foo/foo.map.txt"}
-	for _, expected_file_suffix := range expected_file_suffixes {
-		android.AssertBoolEquals(t, expected_file_suffix+" file not found in input", true, android.SuffixInList(actual_surface_inputs, expected_file_suffix))
-	}
-
-	// check args/inputs to rule
-	/*api_surface_gen_rule_args := result.ModuleForTests("mysdk", "").Rule("genApiSurfaceBuildFiles").Args
-	android.AssertStringEquals(t, "name", "foo.mysdk", api_surface_gen_rule_args["name"])
-	android.AssertStringEquals(t, "symbol_file", "foo.map.txt", api_surface_gen_rule_args["symbol_file"])*/
-}
-
 func hasDirectDependency(t *testing.T, ctx *android.TestResult, from android.Module, to android.Module) bool {
 	t.Helper()
 	var found bool
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 3756810..1842e5a 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -358,12 +358,12 @@
 
 // TODO(b/228623543): The below is not entirely true until the bug is fixed. For now, both targets are always generated
 // Implements bp2build for cc_prebuilt_library modules. This will generate:
-//   - Only a prebuilt_library_static if the shared.enabled property is set to false across all variants.
-//   - Only a prebuilt_library_shared if the static.enabled property is set to false across all variants
-//   - Both a prebuilt_library_static and prebuilt_library_shared if the aforementioned properties are not false across
+//   - Only a cc_prebuilt_library_static if the shared.enabled property is set to false across all variants.
+//   - Only a cc_prebuilt_library_shared if the static.enabled property is set to false across all variants
+//   - Both a cc_prebuilt_library_static and cc_prebuilt_library_shared if the aforementioned properties are not false across
 //     all variants
 //
-// In all cases, prebuilt_library_static target names will be appended with "_bp2build_cc_library_static".
+// In all cases, cc_prebuilt_library_static target names will be appended with "_bp2build_cc_library_static".
 func prebuiltLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module) {
 	prebuiltLibraryStaticBp2Build(ctx, module, true)
 	prebuiltLibrarySharedBp2Build(ctx, module)
@@ -380,8 +380,8 @@
 	}
 
 	props := bazel.BazelTargetModuleProperties{
-		Rule_class:        "prebuilt_library_static",
-		Bzl_load_location: "//build/bazel/rules/cc:prebuilt_library_static.bzl",
+		Rule_class:        "cc_prebuilt_library_static",
+		Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_static.bzl",
 	}
 
 	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
@@ -403,8 +403,8 @@
 	}
 
 	props := bazel.BazelTargetModuleProperties{
-		Rule_class:        "prebuilt_library_shared",
-		Bzl_load_location: "//build/bazel/rules/cc:prebuilt_library_shared.bzl",
+		Rule_class:        "cc_prebuilt_library_shared",
+		Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_shared.bzl",
 	}
 
 	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
diff --git a/cc/sanitize.go b/cc/sanitize.go
index b8cc432..d3fc221 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -619,6 +619,14 @@
 		return flags
 	}
 
+	// Currently unwinding through tagged frames for exceptions is broken, so disable memtag stack
+	// in that case, so we don't end up tagging those.
+	// TODO(b/174878242): Remove once https://r.android.com/2251926 is included in toolchain.
+	if android.InList("-fexceptions", flags.Local.CFlags) || android.InList("-fexceptions", flags.Global.CFlags) {
+		sanitize.Properties.Sanitize.Memtag_stack = nil
+		_, sanitize.Properties.Sanitizers = android.RemoveFromList("memtag-stack", sanitize.Properties.Sanitizers)
+	}
+
 	if Bool(sanitize.Properties.Sanitize.Address) {
 		if ctx.Arch().ArchType == android.Arm {
 			// Frame pointer based unwinder in ASan requires ARM frame setup.
@@ -1390,6 +1398,7 @@
 
 		// Determine the runtime library required
 		runtimeLibrary := ""
+		alwaysStaticRuntime := false
 		var extraStaticDeps []string
 		toolchain := c.toolchain(mctx)
 		if Bool(c.sanitize.Properties.Sanitize.Address) {
@@ -1414,8 +1423,15 @@
 			Bool(c.sanitize.Properties.Sanitize.Undefined) ||
 			Bool(c.sanitize.Properties.Sanitize.All_undefined) {
 			runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain)
-			if c.staticBinary() {
+			if c.staticBinary() || toolchain.Musl() {
+				// Use a static runtime for static binaries.
+				// Also use a static runtime for musl to match
+				// what clang does for glibc.  Otherwise dlopening
+				// libraries that depend on libclang_rt.ubsan_standalone.so
+				// fails with:
+				// Error relocating ...: initial-exec TLS resolves to dynamic definition
 				runtimeLibrary += ".static"
+				alwaysStaticRuntime = true
 			}
 		}
 
@@ -1459,7 +1475,7 @@
 			//
 			// Note that by adding dependency with {static|shared}DepTag, the lib is
 			// added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
-			if c.staticBinary() {
+			if c.staticBinary() || alwaysStaticRuntime {
 				addStaticDeps(runtimeLibrary)
 				addStaticDeps(extraStaticDeps...)
 			} else if !c.static() && !c.Header() {
diff --git a/cc/tidy.go b/cc/tidy.go
index 2ba13ca..810d089 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -79,9 +79,10 @@
 	// Some projects like external/* and vendor/* have clang-tidy disabled by default,
 	// unless they are enabled explicitly with the "tidy:true" property or
 	// when TIDY_EXTERNAL_VENDOR is set to true.
-	if !ctx.Config().IsEnvTrue("TIDY_EXTERNAL_VENDOR") &&
-		!proptools.Bool(tidy.Properties.Tidy) &&
-		config.NoClangTidyForDir(ctx.ModuleDir()) {
+	if !proptools.Bool(tidy.Properties.Tidy) &&
+		config.NoClangTidyForDir(
+			ctx.Config().IsEnvTrue("TIDY_EXTERNAL_VENDOR"),
+			ctx.ModuleDir()) {
 		return flags
 	}
 	// If not explicitly disabled, set flags.Tidy to generate .tidy rules.
diff --git a/cmd/extract_apks/bundle_proto/Android.bp b/cmd/extract_apks/bundle_proto/Android.bp
new file mode 100644
index 0000000..e56c0fb
--- /dev/null
+++ b/cmd/extract_apks/bundle_proto/Android.bp
@@ -0,0 +1,13 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+python_library_host {
+    name: "config_proto",
+    srcs: [
+        "config.proto",
+    ],
+    proto: {
+        canonical_path_from_root: false,
+    },
+}
diff --git a/cmd/extract_apks/bundle_proto/config.proto b/cmd/extract_apks/bundle_proto/config.proto
index d6fac03..946bd9a 100644
--- a/cmd/extract_apks/bundle_proto/config.proto
+++ b/cmd/extract_apks/bundle_proto/config.proto
@@ -26,6 +26,9 @@
     ASSET_ONLY = 2;
   }
   BundleType type = 8;
+
+  // Configuration for locales.
+  Locales locales = 9;
 }
 
 message Bundletool {
@@ -40,6 +43,48 @@
   // the name of the modules, and using forward slash ("/") as a name separator.
   // Examples: "res/raw/**", "assets/**/*.uncompressed", etc.
   repeated string uncompressed_glob = 1;
+
+  enum AssetModuleCompression {
+    UNSPECIFIED = 0;
+    // Assets are left uncompressed in the generated asset module.
+    UNCOMPRESSED = 1;
+    // Assets are compressed in the generated asset module.
+    // This option can be overridden at a finer granularity by specifying
+    // files or folders to keep uncompressed in `uncompressed_glob`.
+    // This option should only be used if the app is able to handle compressed
+    // asset module content at runtime (some runtime APIs may misbehave).
+    COMPRESSED = 2;
+  }
+
+  // Default compression strategy for install-time asset modules.
+  // If the compression strategy indicates to compress a file and the same file
+  // matches one of the `uncompressed_glob` values, the `uncompressed_glob`
+  // takes precedence (the file is left uncompressed in the generated APK).
+  //
+  // If unspecified, asset module content is left uncompressed in the
+  // generated asset modules.
+  //
+  // Note: this flag only configures the compression strategy for install-time
+  // asset modules; the content of on-demand and fast-follow asset modules is
+  // always kept uncompressed.
+  AssetModuleCompression install_time_asset_module_default_compression = 2;
+
+  enum ApkCompressionAlgorithm {
+    // Default in the current version of bundletool is zlib deflate algorithm
+    // with compression level 9 for the application's resources and compression
+    // level 6 for other entries.
+    //
+    // This is a good trade-off between size of final APK and size of patches
+    // which are used to update the application from previous to next version.
+    DEFAULT_APK_COMPRESSION_ALGORITHM = 0;
+
+    // 7zip implementation of deflate algorithm which gives smaller APK size
+    // but size of patches required to update the application are larger.
+    P7ZIP = 1;
+  }
+
+  // Compression algorithm which is used to compress entries in final APKs.
+  ApkCompressionAlgorithm apk_compression_algorithm = 3;
 }
 
 // Resources to keep in the master split.
@@ -55,12 +100,40 @@
   // This is for uncompressing native libraries on M+ devices (L+ devices on
   // instant apps).
   UncompressNativeLibraries uncompress_native_libraries = 2;
-  // This is for uncompressing dex files on P+ devices.
+  // This is for uncompressing dex files.
   UncompressDexFiles uncompress_dex_files = 3;
   // Configuration for the generation of standalone APKs.
   // If no StandaloneConfig is set, the configuration is inherited from
   // splits_config.
   StandaloneConfig standalone_config = 4;
+
+  // Optimizations that are applied to resources.
+  ResourceOptimizations resource_optimizations = 5;
+
+  // Configuration for archiving the app.
+  StoreArchive store_archive = 6;
+}
+
+message ResourceOptimizations {
+  // Whether to use sparse encoding for resource tables.
+  // Resources in sparse resource table are accessed using a binary search tree.
+  // This decreases APK size at the cost of resource retrieval performance.
+  SparseEncoding sparse_encoding = 1;
+
+  enum SparseEncoding {
+    // Previously 'ENFORCED'. This option is deprecated because of issues found
+    // in Android O up to Android Sv2 and causes segfaults in
+    // Resources#getIdentifier.
+    reserved 1;
+    reserved "ENFORCED";
+
+    // Disables sparse encoding.
+    UNSPECIFIED = 0;
+    // Generates special APKs for Android SDK +32 with sparse resource tables.
+    // Devices with Android SDK below 32 will still receive APKs with regular
+    // resource tables.
+    VARIANT_FOR_SDK_32 = 2;
+  }
 }
 
 message UncompressNativeLibraries {
@@ -68,7 +141,39 @@
 }
 
 message UncompressDexFiles {
+  //  A new variant with uncompressed dex will be generated. The sdk targeting
+  //  of the variant is determined by 'uncompressed_dex_target_sdk'.
   bool enabled = 1;
+
+  //  If 'enabled' field is set, this will determine the sdk targeting of the
+  //  generated variant.
+  UncompressedDexTargetSdk uncompressed_dex_target_sdk = 2;
+
+  enum UncompressedDexTargetSdk {
+    // Q+ variant will be generated.
+    UNSPECIFIED = 0;
+    // S+ variant will be generated.
+    SDK_31 = 1;
+  }
+}
+
+message StoreArchive {
+  // Archive is an app state that allows an official app store to reclaim device
+  // storage and disable app functionality temporarily until the user interacts
+  // with the app again. Upon interaction the latest available version of the
+  // app will be restored while leaving user data unaffected.
+  // Enabled by default.
+  bool enabled = 1;
+}
+
+message Locales {
+  // Instructs bundletool to generate locale config and inject it into
+  // AndroidManifest.xml. A locale is marked as supported by the application if
+  // there is at least one resource value in this locale. Be very careful with
+  // this setting because if some of your libraries expose resources in some
+  // locales which are not actually supported by your application it will mark
+  // this locale as supported. Disabled by default.
+  bool inject_locale_config = 1;
 }
 
 // Optimization configuration used to generate Split APKs.
@@ -82,8 +187,28 @@
   repeated SplitDimension split_dimension = 1;
   // Whether 64 bit libraries should be stripped from Standalone APKs.
   bool strip_64_bit_libraries = 2;
+  // Dex merging strategy that should be applied to produce Standalone APKs.
+  DexMergingStrategy dex_merging_strategy = 3;
+
+  enum DexMergingStrategy {
+    // Strategy that does dex merging for applications that have minimum SDK
+    // below 21 to ensure dex files from all modules are merged into one or
+    // mainDexList is applied when merging into one dex is not possible. For
+    // applications with minSdk >= 21 dex files from all modules are copied into
+    // standalone APK as is because Android supports multiple dex files natively
+    // starting from Android 5.0.
+    MERGE_IF_NEEDED = 0;
+    // Requires to copy dex files from all modules into standalone APK as is.
+    // If an application supports SDKs below 21 this strategy puts
+    // responsibility of providing dex files compatible with legacy multidex on
+    // application developers.
+    NEVER_MERGE = 1;
+  }
 }
 
+// BEGIN-INTERNAL
+// LINT.IfChange
+// END-INTERNAL
 message SplitDimension {
   enum Value {
     UNSPECIFIED_VALUE = 0;
@@ -92,8 +217,9 @@
     LANGUAGE = 3;
     TEXTURE_COMPRESSION_FORMAT = 4;
     // BEGIN-INTERNAL
-    GRAPHICS_API = 5;
+    GRAPHICS_API = 5 [deprecated = true];
     // END-INTERNAL
+    DEVICE_TIER = 6;
   }
   Value value = 1;
 
@@ -105,11 +231,14 @@
   // the targeting is encoded in the directory name (e.g: assets/foo#tcf_etc1)
   SuffixStripping suffix_stripping = 3;
 }
+// BEGIN-INTERNAL
+// LINT.ThenChange(//depot/google3/wireless/android/vending/developer/proto/storage/app/apk_bundle.proto)
+// END-INTERNAL
 
 message SuffixStripping {
   // If set to 'true', indicates that the targeting suffix should be removed
-  // from assets paths for this dimension when splits (or asset slices) are
-  // generated.
+  // from assets paths for this dimension when splits (e.g: "asset packs") or
+  // standalone/universal APKs are generated.
   // This only applies to assets.
   // For example a folder with path "assets/level1_textures#tcf_etc1"
   // would be outputted to "assets/level1_textures". File contents are
@@ -117,9 +246,9 @@
   bool enabled = 1;
 
   // The default suffix to be used for the cases where separate slices can't
-  // be generated for this dimension. In the case of standalone/universal APKs
-  // generation, stripping the suffix can lead to file name collisions. This
-  // default suffix defines the directories to retain. The others are
+  // be generated for this dimension - typically for standalone or universal
+  // APKs.
+  // This default suffix defines the directories to retain. The others are
   // discarded: standalone/universal APKs will contain only directories
   // targeted at this value for the dimension.
   //
@@ -135,6 +264,15 @@
 message ApexConfig {
   // Configuration for processing of APKs embedded in an APEX image.
   repeated ApexEmbeddedApkConfig apex_embedded_apk_config = 1;
+
+  // Explicit list of supported ABIs.
+  // Default: See ApexBundleValidator.REQUIRED_ONE_OF_ABI_SETS
+  repeated SupportedAbiSet supported_abi_set = 2;
+}
+
+// Represents a set of ABIs which must be supported by a single APEX image.
+message SupportedAbiSet {
+  repeated string abi = 1;
 }
 
 message ApexEmbeddedApkConfig {
diff --git a/compliance/project_metadata_proto/Android.bp b/compliance/project_metadata_proto/Android.bp
new file mode 100644
index 0000000..56e76e7
--- /dev/null
+++ b/compliance/project_metadata_proto/Android.bp
@@ -0,0 +1,27 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+    name: "project_metadata_proto",
+    pkgPath: "android/soong/compliance/project_metadata_proto",
+    srcs: ["project_metadata.pb.go"],
+    deps: [
+        "golang-protobuf-reflect-protoreflect",
+        "golang-protobuf-runtime-protoimpl",
+    ],
+}
diff --git a/compliance/project_metadata_proto/project_metadata.pb.go b/compliance/project_metadata_proto/project_metadata.pb.go
new file mode 100644
index 0000000..529159c
--- /dev/null
+++ b/compliance/project_metadata_proto/project_metadata.pb.go
@@ -0,0 +1,765 @@
+// 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.
+
+// A proto definition used to parse METADATA file in third party projects.
+
+// This proto will only contain fields and values used by android compliance.
+// It is not intended to be the formal definition of METADATA file.
+
+// See google3/third_party/metadata.proto if you need to add more stuff to
+// match upstream. Do not add new fields and values here. Add them upstream
+// when necessary, and copy them here.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.0
+// 	protoc        v3.12.4
+// source: project_metadata.proto
+
+package project_metadata_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)
+)
+
+// License type that identifies how the packages may be used. See
+// go/thirdpartylicenses for full explanation of each license type.
+type LicenseType int32
+
+const (
+	LicenseType_BY_EXCEPTION_ONLY               LicenseType = 1
+	LicenseType_NOTICE                          LicenseType = 2
+	LicenseType_PERMISSIVE                      LicenseType = 3
+	LicenseType_RECIPROCAL                      LicenseType = 4
+	LicenseType_RESTRICTED_IF_STATICALLY_LINKED LicenseType = 5
+	LicenseType_RESTRICTED                      LicenseType = 6
+	LicenseType_UNENCUMBERED                    LicenseType = 7
+)
+
+// Enum value maps for LicenseType.
+var (
+	LicenseType_name = map[int32]string{
+		1: "BY_EXCEPTION_ONLY",
+		2: "NOTICE",
+		3: "PERMISSIVE",
+		4: "RECIPROCAL",
+		5: "RESTRICTED_IF_STATICALLY_LINKED",
+		6: "RESTRICTED",
+		7: "UNENCUMBERED",
+	}
+	LicenseType_value = map[string]int32{
+		"BY_EXCEPTION_ONLY":               1,
+		"NOTICE":                          2,
+		"PERMISSIVE":                      3,
+		"RECIPROCAL":                      4,
+		"RESTRICTED_IF_STATICALLY_LINKED": 5,
+		"RESTRICTED":                      6,
+		"UNENCUMBERED":                    7,
+	}
+)
+
+func (x LicenseType) Enum() *LicenseType {
+	p := new(LicenseType)
+	*p = x
+	return p
+}
+
+func (x LicenseType) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (LicenseType) Descriptor() protoreflect.EnumDescriptor {
+	return file_project_metadata_proto_enumTypes[0].Descriptor()
+}
+
+func (LicenseType) Type() protoreflect.EnumType {
+	return &file_project_metadata_proto_enumTypes[0]
+}
+
+func (x LicenseType) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *LicenseType) UnmarshalJSON(b []byte) error {
+	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+	if err != nil {
+		return err
+	}
+	*x = LicenseType(num)
+	return nil
+}
+
+// Deprecated: Use LicenseType.Descriptor instead.
+func (LicenseType) EnumDescriptor() ([]byte, []int) {
+	return file_project_metadata_proto_rawDescGZIP(), []int{0}
+}
+
+type URL_Type int32
+
+const (
+	// The homepage for the package. For example, "https://bazel.io/". This URL
+	// is optional, but encouraged to help disambiguate similarly named packages
+	// or to get more information about the package. This is especially helpful
+	// when no other URLs provide human readable resources (such as git:// or
+	// sso:// URLs).
+	URL_HOMEPAGE URL_Type = 1
+	// The URL of the archive containing the source code for the package, for
+	// example a zip or tgz file.
+	URL_ARCHIVE URL_Type = 2
+	// The URL of the upstream git repository this package is retrieved from.
+	// For example:
+	//   - https://github.com/git/git.git
+	//   - git://git.kernel.org/pub/scm/git/git.git
+	//
+	// Use of a git URL requires that the package "version" value must specify a
+	// specific git tag or revision.
+	URL_GIT URL_Type = 3
+	// The URL of the upstream SVN repository this package is retrieved from.
+	// For example:
+	//   - http://llvm.org/svn/llvm-project/llvm/
+	//
+	// Use of an SVN URL requires that the package "version" value must specify
+	// a specific SVN tag or revision.
+	URL_SVN URL_Type = 7
+	// The URL of the upstream mercurial repository this package is retrieved
+	// from. For example:
+	//   - https://mercurial-scm.org/repo/evolve
+	//
+	// Use of a mercurial URL requires that the package "version" value must
+	// specify a specific tag or revision.
+	URL_HG URL_Type = 8
+	// The URL of the upstream darcs repository this package is retrieved
+	// from. For example:
+	//   - https://hub.darcs.net/hu.dwim/hu.dwim.util
+	//
+	// Use of a DARCS URL requires that the package "version" value must
+	// specify a specific tag or revision.
+	URL_DARCS URL_Type = 9
+	// The URL of the upstream piper location.  This is primarily used when a
+	// package is being migrated into third_party from elsewhere in piper, or
+	// when a package is being newly developed in third_party.  For newly
+	// developed packages, the PIPER URL should reference the package itself
+	// (e.g. "http://google3/third_party/my/package")
+	URL_PIPER URL_Type = 4
+	// A URL that does not fit any other type. This may also indicate that the
+	// source code was received via email or some other out-of-band way. This is
+	// most commonly used with commercial software received directly from the
+	// vendor. In the case of email, the URL value can be used to provide
+	// additional information about how it was received.
+	URL_OTHER URL_Type = 11
+	// The URL identifying where the local copy of the package source code can
+	// be found.
+	//
+	// Typically, the metadata files describing a package reside in the same
+	// directory as the source code for the package. In a few rare cases where
+	// they are separate, the LOCAL_SOURCE URL identifies where to find the
+	// source code. This only describes where to find the local copy of the
+	// source; there should always be an additional URL describing where the
+	// package was retrieved from.
+	//
+	// Examples:
+	//   - http://google3/third_party/java_src/gerritcodereview/gerrit/
+	//   - https://android.googlesource.com/platform/external/apache-http/
+	URL_LOCAL_SOURCE URL_Type = 6
+)
+
+// Enum value maps for URL_Type.
+var (
+	URL_Type_name = map[int32]string{
+		1:  "HOMEPAGE",
+		2:  "ARCHIVE",
+		3:  "GIT",
+		7:  "SVN",
+		8:  "HG",
+		9:  "DARCS",
+		4:  "PIPER",
+		11: "OTHER",
+		6:  "LOCAL_SOURCE",
+	}
+	URL_Type_value = map[string]int32{
+		"HOMEPAGE":     1,
+		"ARCHIVE":      2,
+		"GIT":          3,
+		"SVN":          7,
+		"HG":           8,
+		"DARCS":        9,
+		"PIPER":        4,
+		"OTHER":        11,
+		"LOCAL_SOURCE": 6,
+	}
+)
+
+func (x URL_Type) Enum() *URL_Type {
+	p := new(URL_Type)
+	*p = x
+	return p
+}
+
+func (x URL_Type) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (URL_Type) Descriptor() protoreflect.EnumDescriptor {
+	return file_project_metadata_proto_enumTypes[1].Descriptor()
+}
+
+func (URL_Type) Type() protoreflect.EnumType {
+	return &file_project_metadata_proto_enumTypes[1]
+}
+
+func (x URL_Type) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *URL_Type) UnmarshalJSON(b []byte) error {
+	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+	if err != nil {
+		return err
+	}
+	*x = URL_Type(num)
+	return nil
+}
+
+// Deprecated: Use URL_Type.Descriptor instead.
+func (URL_Type) EnumDescriptor() ([]byte, []int) {
+	return file_project_metadata_proto_rawDescGZIP(), []int{2, 0}
+}
+
+type Metadata struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Name of this API/package.
+	Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	// A short description (a few lines) of the package. It will be
+	// included on the summary page.
+	// Example: "Handles location lookups, throttling, batching, etc."
+	Description *string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"`
+	// Specifies additional data about third-party packages.
+	ThirdParty *ThirdParty `protobuf:"bytes,13,opt,name=third_party,json=thirdParty" json:"third_party,omitempty"`
+}
+
+func (x *Metadata) Reset() {
+	*x = Metadata{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_project_metadata_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Metadata) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Metadata) ProtoMessage() {}
+
+func (x *Metadata) ProtoReflect() protoreflect.Message {
+	mi := &file_project_metadata_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 Metadata.ProtoReflect.Descriptor instead.
+func (*Metadata) Descriptor() ([]byte, []int) {
+	return file_project_metadata_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Metadata) GetName() string {
+	if x != nil && x.Name != nil {
+		return *x.Name
+	}
+	return ""
+}
+
+func (x *Metadata) GetDescription() string {
+	if x != nil && x.Description != nil {
+		return *x.Description
+	}
+	return ""
+}
+
+func (x *Metadata) GetThirdParty() *ThirdParty {
+	if x != nil {
+		return x.ThirdParty
+	}
+	return nil
+}
+
+type ThirdParty struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// URL(s) associated with the package.
+	//
+	// At a minimum, all packages must specify a URL which identifies where it
+	// came from, containing a type of: ARCHIVE, GIT, PIPER, or OTHER. Typically,
+	// a package should contain only a single URL from these types.  Occasionally,
+	// a package may be broken across multiple archive files for whatever reason,
+	// in which case having multiple ARCHIVE URLs is okay.  However, this should
+	// not be used to combine different logical packages that are versioned and
+	// possibly licensed differently.
+	Url []*URL `protobuf:"bytes,1,rep,name=url" json:"url,omitempty"`
+	// The package version.  In order of preference, this should contain:
+	//   - If the package comes from Git or another source control system,
+	//     a specific tag or revision in source control, such as "r123" or
+	//     "58e27d2".  This MUST NOT be a mutable ref such as a branch name.
+	//   - a released package version such as "1.0", "2.3-beta", etc.
+	//   - the date the package was retrieved, formatted as "As of YYYY-MM-DD".
+	Version *string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
+	// The date of the change in which the package was last upgraded from
+	// upstream.
+	// This should only identify package upgrades from upstream, not local
+	// modifications. This may identify the date of either the original or
+	// merged change.
+	//
+	// Note: this is NOT the date that this version of the package was released
+	// externally.
+	LastUpgradeDate *Date `protobuf:"bytes,10,opt,name=last_upgrade_date,json=lastUpgradeDate" json:"last_upgrade_date,omitempty"`
+	// License type that identifies how the package may be used. See
+	// go/thirdpartylicenses for instructions on selecting the appropriate type.
+	LicenseType *LicenseType `protobuf:"varint,4,opt,name=license_type,json=licenseType,enum=project_metadata.LicenseType" json:"license_type,omitempty"`
+	// Description of local changes that have been made to the package.  This does
+	// not need to (and in most cases should not) attempt to include an exhaustive
+	// list of all changes, but may instead direct readers to review the local
+	// commit history, a collection of patch files, a separate README.md (or
+	// similar) document, etc.
+	// Note: Use of this field to store IDs of advisories fixed with a backported
+	// patch is deprecated, use "security.mitigated_security_patch" instead.
+	LocalModifications *string `protobuf:"bytes,6,opt,name=local_modifications,json=localModifications" json:"local_modifications,omitempty"`
+	// The URL for any public mirror created for compliance purposes.
+	// See go/thirdpartylicenses#reciprocal policy for more details.
+	ComplianceMirrorUrl *string `protobuf:"bytes,12,opt,name=compliance_mirror_url,json=complianceMirrorUrl" json:"compliance_mirror_url,omitempty"`
+	// The homepage for the package. This will eventually replace
+	// `url { type: HOMEPAGE }`
+	Homepage *string `protobuf:"bytes,14,opt,name=homepage" json:"homepage,omitempty"`
+}
+
+func (x *ThirdParty) Reset() {
+	*x = ThirdParty{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_project_metadata_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ThirdParty) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ThirdParty) ProtoMessage() {}
+
+func (x *ThirdParty) ProtoReflect() protoreflect.Message {
+	mi := &file_project_metadata_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 ThirdParty.ProtoReflect.Descriptor instead.
+func (*ThirdParty) Descriptor() ([]byte, []int) {
+	return file_project_metadata_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *ThirdParty) GetUrl() []*URL {
+	if x != nil {
+		return x.Url
+	}
+	return nil
+}
+
+func (x *ThirdParty) GetVersion() string {
+	if x != nil && x.Version != nil {
+		return *x.Version
+	}
+	return ""
+}
+
+func (x *ThirdParty) GetLastUpgradeDate() *Date {
+	if x != nil {
+		return x.LastUpgradeDate
+	}
+	return nil
+}
+
+func (x *ThirdParty) GetLicenseType() LicenseType {
+	if x != nil && x.LicenseType != nil {
+		return *x.LicenseType
+	}
+	return LicenseType_BY_EXCEPTION_ONLY
+}
+
+func (x *ThirdParty) GetLocalModifications() string {
+	if x != nil && x.LocalModifications != nil {
+		return *x.LocalModifications
+	}
+	return ""
+}
+
+func (x *ThirdParty) GetComplianceMirrorUrl() string {
+	if x != nil && x.ComplianceMirrorUrl != nil {
+		return *x.ComplianceMirrorUrl
+	}
+	return ""
+}
+
+func (x *ThirdParty) GetHomepage() string {
+	if x != nil && x.Homepage != nil {
+		return *x.Homepage
+	}
+	return ""
+}
+
+// URL associated with a third-party package.
+type URL struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The type of resource this URL identifies.
+	Type *URL_Type `protobuf:"varint,1,opt,name=type,enum=project_metadata.URL_Type" json:"type,omitempty"`
+	// The actual URL value.  URLs should be absolute and start with 'http://' or
+	// 'https://' (or occasionally 'git://' or 'ftp://' where appropriate).
+	Value *string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
+}
+
+func (x *URL) Reset() {
+	*x = URL{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_project_metadata_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *URL) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*URL) ProtoMessage() {}
+
+func (x *URL) ProtoReflect() protoreflect.Message {
+	mi := &file_project_metadata_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 URL.ProtoReflect.Descriptor instead.
+func (*URL) Descriptor() ([]byte, []int) {
+	return file_project_metadata_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *URL) GetType() URL_Type {
+	if x != nil && x.Type != nil {
+		return *x.Type
+	}
+	return URL_HOMEPAGE
+}
+
+func (x *URL) GetValue() string {
+	if x != nil && x.Value != nil {
+		return *x.Value
+	}
+	return ""
+}
+
+// Represents a whole or partial calendar date, such as a birthday. The time of
+// day and time zone are either specified elsewhere or are insignificant. The
+// date is relative to the Gregorian Calendar. This can represent one of the
+// following:
+//
+//   - A full date, with non-zero year, month, and day values.
+//   - A month and day, with a zero year (for example, an anniversary).
+//   - A year on its own, with a zero month and a zero day.
+//   - A year and month, with a zero day (for example, a credit card expiration
+//     date).
+type Date struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Year of the date. Must be from 1 to 9999, or 0 to specify a date without
+	// a year.
+	Year *int32 `protobuf:"varint,1,opt,name=year" json:"year,omitempty"`
+	// Month of a year. Must be from 1 to 12, or 0 to specify a year without a
+	// month and day.
+	Month *int32 `protobuf:"varint,2,opt,name=month" json:"month,omitempty"`
+	// Day of a month. Must be from 1 to 31 and valid for the year and month, or 0
+	// to specify a year by itself or a year and month where the day isn't
+	// significant.
+	Day *int32 `protobuf:"varint,3,opt,name=day" json:"day,omitempty"`
+}
+
+func (x *Date) Reset() {
+	*x = Date{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_project_metadata_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Date) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Date) ProtoMessage() {}
+
+func (x *Date) ProtoReflect() protoreflect.Message {
+	mi := &file_project_metadata_proto_msgTypes[3]
+	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 Date.ProtoReflect.Descriptor instead.
+func (*Date) Descriptor() ([]byte, []int) {
+	return file_project_metadata_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *Date) GetYear() int32 {
+	if x != nil && x.Year != nil {
+		return *x.Year
+	}
+	return 0
+}
+
+func (x *Date) GetMonth() int32 {
+	if x != nil && x.Month != nil {
+		return *x.Month
+	}
+	return 0
+}
+
+func (x *Date) GetDay() int32 {
+	if x != nil && x.Day != nil {
+		return *x.Day
+	}
+	return 0
+}
+
+var File_project_metadata_proto protoreflect.FileDescriptor
+
+var file_project_metadata_proto_rawDesc = []byte{
+	0x0a, 0x16, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
+	0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x7f, 0x0a, 0x08, 0x4d, 0x65,
+	0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,
+	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0b,
+	0x74, 0x68, 0x69, 0x72, 0x64, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61,
+	0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x52,
+	0x0a, 0x74, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x22, 0xd6, 0x02, 0x0a, 0x0a,
+	0x54, 0x68, 0x69, 0x72, 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x12, 0x27, 0x0a, 0x03, 0x75, 0x72,
+	0x6c, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x52, 0x4c, 0x52, 0x03,
+	0x75, 0x72, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a,
+	0x11, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x5f, 0x64, 0x61,
+	0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x6a, 0x65,
+	0x63, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x65,
+	0x52, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x44, 0x61, 0x74,
+	0x65, 0x12, 0x40, 0x0a, 0x0c, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70,
+	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
+	0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e,
+	0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x54,
+	0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6d, 0x6f, 0x64,
+	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e,
+	0x63, 0x65, 0x5f, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0c, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x13, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x4d,
+	0x69, 0x72, 0x72, 0x6f, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x6d, 0x65,
+	0x70, 0x61, 0x67, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x6d, 0x65,
+	0x70, 0x61, 0x67, 0x65, 0x22, 0xbb, 0x01, 0x0a, 0x03, 0x55, 0x52, 0x4c, 0x12, 0x2e, 0x0a, 0x04,
+	0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x52,
+	0x4c, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
+	0x75, 0x65, 0x22, 0x6e, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x48, 0x4f,
+	0x4d, 0x45, 0x50, 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x52, 0x43, 0x48,
+	0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x47, 0x49, 0x54, 0x10, 0x03, 0x12, 0x07,
+	0x0a, 0x03, 0x53, 0x56, 0x4e, 0x10, 0x07, 0x12, 0x06, 0x0a, 0x02, 0x48, 0x47, 0x10, 0x08, 0x12,
+	0x09, 0x0a, 0x05, 0x44, 0x41, 0x52, 0x43, 0x53, 0x10, 0x09, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x49,
+	0x50, 0x45, 0x52, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b,
+	0x12, 0x10, 0x0a, 0x0c, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x5f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45,
+	0x10, 0x06, 0x22, 0x42, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x65,
+	0x61, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x79, 0x65, 0x61, 0x72, 0x12, 0x14,
+	0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d,
+	0x6f, 0x6e, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x05, 0x52, 0x03, 0x64, 0x61, 0x79, 0x2a, 0x97, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e,
+	0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x59, 0x5f, 0x45, 0x58, 0x43,
+	0x45, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x0a, 0x0a,
+	0x06, 0x4e, 0x4f, 0x54, 0x49, 0x43, 0x45, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x45, 0x52,
+	0x4d, 0x49, 0x53, 0x53, 0x49, 0x56, 0x45, 0x10, 0x03, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x43,
+	0x49, 0x50, 0x52, 0x4f, 0x43, 0x41, 0x4c, 0x10, 0x04, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x53,
+	0x54, 0x52, 0x49, 0x43, 0x54, 0x45, 0x44, 0x5f, 0x49, 0x46, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49,
+	0x43, 0x41, 0x4c, 0x4c, 0x59, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x45, 0x44, 0x10, 0x05, 0x12, 0x0e,
+	0x0a, 0x0a, 0x52, 0x45, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x45, 0x44, 0x10, 0x06, 0x12, 0x10,
+	0x0a, 0x0c, 0x55, 0x4e, 0x45, 0x4e, 0x43, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x45, 0x44, 0x10, 0x07,
+	0x42, 0x31, 0x5a, 0x2f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e,
+	0x67, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x70, 0x72, 0x6f,
+	0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x70, 0x72,
+	0x6f, 0x74, 0x6f,
+}
+
+var (
+	file_project_metadata_proto_rawDescOnce sync.Once
+	file_project_metadata_proto_rawDescData = file_project_metadata_proto_rawDesc
+)
+
+func file_project_metadata_proto_rawDescGZIP() []byte {
+	file_project_metadata_proto_rawDescOnce.Do(func() {
+		file_project_metadata_proto_rawDescData = protoimpl.X.CompressGZIP(file_project_metadata_proto_rawDescData)
+	})
+	return file_project_metadata_proto_rawDescData
+}
+
+var file_project_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_project_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_project_metadata_proto_goTypes = []interface{}{
+	(LicenseType)(0),   // 0: project_metadata.LicenseType
+	(URL_Type)(0),      // 1: project_metadata.URL.Type
+	(*Metadata)(nil),   // 2: project_metadata.Metadata
+	(*ThirdParty)(nil), // 3: project_metadata.ThirdParty
+	(*URL)(nil),        // 4: project_metadata.URL
+	(*Date)(nil),       // 5: project_metadata.Date
+}
+var file_project_metadata_proto_depIdxs = []int32{
+	3, // 0: project_metadata.Metadata.third_party:type_name -> project_metadata.ThirdParty
+	4, // 1: project_metadata.ThirdParty.url:type_name -> project_metadata.URL
+	5, // 2: project_metadata.ThirdParty.last_upgrade_date:type_name -> project_metadata.Date
+	0, // 3: project_metadata.ThirdParty.license_type:type_name -> project_metadata.LicenseType
+	1, // 4: project_metadata.URL.type:type_name -> project_metadata.URL.Type
+	5, // [5:5] is the sub-list for method output_type
+	5, // [5:5] is the sub-list for method input_type
+	5, // [5:5] is the sub-list for extension type_name
+	5, // [5:5] is the sub-list for extension extendee
+	0, // [0:5] is the sub-list for field type_name
+}
+
+func init() { file_project_metadata_proto_init() }
+func file_project_metadata_proto_init() {
+	if File_project_metadata_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_project_metadata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Metadata); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_project_metadata_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ThirdParty); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_project_metadata_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*URL); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_project_metadata_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Date); 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_project_metadata_proto_rawDesc,
+			NumEnums:      2,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_project_metadata_proto_goTypes,
+		DependencyIndexes: file_project_metadata_proto_depIdxs,
+		EnumInfos:         file_project_metadata_proto_enumTypes,
+		MessageInfos:      file_project_metadata_proto_msgTypes,
+	}.Build()
+	File_project_metadata_proto = out.File
+	file_project_metadata_proto_rawDesc = nil
+	file_project_metadata_proto_goTypes = nil
+	file_project_metadata_proto_depIdxs = nil
+}
diff --git a/compliance/project_metadata_proto/project_metadata.proto b/compliance/project_metadata_proto/project_metadata.proto
new file mode 100644
index 0000000..94cc516
--- /dev/null
+++ b/compliance/project_metadata_proto/project_metadata.proto
@@ -0,0 +1,225 @@
+// 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.
+
+// A proto definition used to parse METADATA file in third party projects.
+
+// This proto will only contain fields and values used by android compliance.
+// It is not intended to be the formal definition of METADATA file.
+
+// See google3/third_party/metadata.proto if you need to add more stuff to
+// match upstream. Do not add new fields and values here. Add them upstream
+// when necessary, and copy them here.
+
+syntax = "proto2"; // As long as upstream is proto2...
+
+package project_metadata;
+option go_package = "android/soong/compliance/project_metadata_proto";
+
+// Definitions for project metadata. (go/thirdparty/metadata)
+
+// Special naming conventions:
+// Repeated fields should have singular names (instead of plural).
+
+message Metadata {
+  // Name of this API/package.
+  optional string name = 1;
+
+  // A short description (a few lines) of the package. It will be
+  // included on the summary page.
+  // Example: "Handles location lookups, throttling, batching, etc."
+  optional string description = 3;
+
+  // Specifies additional data about third-party packages.
+  optional ThirdParty third_party = 13;
+}
+
+message ThirdParty {
+  // The name and description for the package should be specified using the top
+  // level fields in MetaData above
+  //
+  // Description should only specify a short description (a few lines) of the
+  // packages. Instructions for maintainers or similar information should be
+  // specified in BUILD comments, a separate README.md file, etc.
+
+  // URL(s) associated with the package.
+  //
+  // At a minimum, all packages must specify a URL which identifies where it
+  // came from, containing a type of: ARCHIVE, GIT, PIPER, or OTHER. Typically,
+  // a package should contain only a single URL from these types.  Occasionally,
+  // a package may be broken across multiple archive files for whatever reason,
+  // in which case having multiple ARCHIVE URLs is okay.  However, this should
+  // not be used to combine different logical packages that are versioned and
+  // possibly licensed differently.
+  repeated URL url = 1;
+
+  // The package version.  In order of preference, this should contain:
+  //  - If the package comes from Git or another source control system,
+  //    a specific tag or revision in source control, such as "r123" or
+  //    "58e27d2".  This MUST NOT be a mutable ref such as a branch name.
+  //  - a released package version such as "1.0", "2.3-beta", etc.
+  //  - the date the package was retrieved, formatted as "As of YYYY-MM-DD".
+  optional string version = 2;
+
+  // The date of the change in which the package was last upgraded from
+  // upstream.
+  // This should only identify package upgrades from upstream, not local
+  // modifications. This may identify the date of either the original or
+  // merged change.
+  //
+  // Note: this is NOT the date that this version of the package was released
+  // externally.
+  optional Date last_upgrade_date = 10;
+
+  // License type that identifies how the package may be used. See
+  // go/thirdpartylicenses for instructions on selecting the appropriate type.
+  optional LicenseType license_type = 4;
+
+  // Description of local changes that have been made to the package.  This does
+  // not need to (and in most cases should not) attempt to include an exhaustive
+  // list of all changes, but may instead direct readers to review the local
+  // commit history, a collection of patch files, a separate README.md (or
+  // similar) document, etc.
+  // Note: Use of this field to store IDs of advisories fixed with a backported
+  // patch is deprecated, use "security.mitigated_security_patch" instead.
+  optional string local_modifications = 6;
+
+  // The URL for any public mirror created for compliance purposes.
+  // See go/thirdpartylicenses#reciprocal policy for more details.
+  optional string compliance_mirror_url = 12;
+
+  // The homepage for the package. This will eventually replace
+  // `url { type: HOMEPAGE }`
+  optional string homepage = 14;
+}
+
+// URL associated with a third-party package.
+message URL {
+  enum Type {
+    // The homepage for the package. For example, "https://bazel.io/". This URL
+    // is optional, but encouraged to help disambiguate similarly named packages
+    // or to get more information about the package. This is especially helpful
+    // when no other URLs provide human readable resources (such as git:// or
+    // sso:// URLs).
+    HOMEPAGE = 1;
+
+    // The URL of the archive containing the source code for the package, for
+    // example a zip or tgz file.
+    ARCHIVE = 2;
+
+    // The URL of the upstream git repository this package is retrieved from.
+    // For example:
+    //  - https://github.com/git/git.git
+    //  - git://git.kernel.org/pub/scm/git/git.git
+    //
+    // Use of a git URL requires that the package "version" value must specify a
+    // specific git tag or revision.
+    GIT = 3;
+
+    // The URL of the upstream SVN repository this package is retrieved from.
+    // For example:
+    //  - http://llvm.org/svn/llvm-project/llvm/
+    //
+    // Use of an SVN URL requires that the package "version" value must specify
+    // a specific SVN tag or revision.
+    SVN = 7;
+
+    // The URL of the upstream mercurial repository this package is retrieved
+    // from. For example:
+    //   - https://mercurial-scm.org/repo/evolve
+    //
+    // Use of a mercurial URL requires that the package "version" value must
+    // specify a specific tag or revision.
+    HG = 8;
+
+    // The URL of the upstream darcs repository this package is retrieved
+    // from. For example:
+    //   - https://hub.darcs.net/hu.dwim/hu.dwim.util
+    //
+    // Use of a DARCS URL requires that the package "version" value must
+    // specify a specific tag or revision.
+    DARCS = 9;
+
+    // The URL of the upstream piper location.  This is primarily used when a
+    // package is being migrated into third_party from elsewhere in piper, or
+    // when a package is being newly developed in third_party.  For newly
+    // developed packages, the PIPER URL should reference the package itself
+    // (e.g. "http://google3/third_party/my/package")
+    PIPER = 4;
+
+    // A URL that does not fit any other type. This may also indicate that the
+    // source code was received via email or some other out-of-band way. This is
+    // most commonly used with commercial software received directly from the
+    // vendor. In the case of email, the URL value can be used to provide
+    // additional information about how it was received.
+    OTHER = 11;
+
+    // The URL identifying where the local copy of the package source code can
+    // be found.
+    //
+    // Typically, the metadata files describing a package reside in the same
+    // directory as the source code for the package. In a few rare cases where
+    // they are separate, the LOCAL_SOURCE URL identifies where to find the
+    // source code. This only describes where to find the local copy of the
+    // source; there should always be an additional URL describing where the
+    // package was retrieved from.
+    //
+    // Examples:
+    //  - http://google3/third_party/java_src/gerritcodereview/gerrit/
+    //  - https://android.googlesource.com/platform/external/apache-http/
+    LOCAL_SOURCE = 6;
+  }
+
+  // The type of resource this URL identifies.
+  optional Type type = 1;
+
+  // The actual URL value.  URLs should be absolute and start with 'http://' or
+  // 'https://' (or occasionally 'git://' or 'ftp://' where appropriate).
+  optional string value = 2;
+}
+
+// License type that identifies how the packages may be used. See
+// go/thirdpartylicenses for full explanation of each license type.
+enum LicenseType {
+  BY_EXCEPTION_ONLY = 1;
+  NOTICE = 2;
+  PERMISSIVE = 3;
+  RECIPROCAL = 4;
+  RESTRICTED_IF_STATICALLY_LINKED = 5;
+  RESTRICTED = 6;
+  UNENCUMBERED = 7;
+}
+
+
+// Represents a whole or partial calendar date, such as a birthday. The time of
+// day and time zone are either specified elsewhere or are insignificant. The
+// date is relative to the Gregorian Calendar. This can represent one of the
+// following:
+//
+// * A full date, with non-zero year, month, and day values.
+// * A month and day, with a zero year (for example, an anniversary).
+// * A year on its own, with a zero month and a zero day.
+// * A year and month, with a zero day (for example, a credit card expiration
+//   date).
+message Date {
+  // Year of the date. Must be from 1 to 9999, or 0 to specify a date without
+  // a year.
+  optional int32 year = 1;
+  // Month of a year. Must be from 1 to 12, or 0 to specify a year without a
+  // month and day.
+  optional int32 month = 2;
+  // Day of a month. Must be from 1 to 31 and valid for the year and month, or 0
+  // to specify a year by itself or a year and month where the day isn't
+  // significant.
+  optional int32 day = 3;
+}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index d4ed363..14895c9 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -875,7 +875,7 @@
 
 type genRuleProperties struct {
 	// names of the output files that will be generated
-	Out []string `android:"arch_variant"`
+	Out []string
 }
 
 type bazelGenruleAttributes struct {
@@ -893,11 +893,27 @@
 	tools_prop.Append(tool_files_prop)
 
 	tools := bazel.MakeLabelListAttribute(tools_prop)
-	srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs))
+	srcs := bazel.LabelListAttribute{}
+	srcs_labels := bazel.LabelList{}
+	// Only cc_genrule is arch specific
+	if ctx.ModuleType() == "cc_genrule" {
+		for axis, configToProps := range m.GetArchVariantProperties(ctx, &generatorProperties{}) {
+			for config, props := range configToProps {
+				if props, ok := props.(*generatorProperties); ok {
+					labels := android.BazelLabelForModuleSrcExcludes(ctx, props.Srcs, props.Exclude_srcs)
+					srcs_labels.Append(labels)
+					srcs.SetSelectValue(axis, config, labels)
+				}
+			}
+		}
+	} else {
+		srcs_labels = android.BazelLabelForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
+		srcs = bazel.MakeLabelListAttribute(srcs_labels)
+	}
 
 	var allReplacements bazel.LabelList
 	allReplacements.Append(tools.Value)
-	allReplacements.Append(srcs.Value)
+	allReplacements.Append(bazel.FirstUniqueBazelLabelList(srcs_labels))
 
 	// Replace in and out variables with $< and $@
 	var cmd string
diff --git a/java/app.go b/java/app.go
index bbd9d2d..2a51e10 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1486,22 +1486,8 @@
 	*bazelAapt
 	Deps             bazel.LabelListAttribute
 	Custom_package   *string
-	Certificate      *bazel.Label
-	Certificate_name *string
-}
-
-// ParseCertificateToAttribute splits the certificate prop into a certificate
-// label attribute or a certificate_name string attribute.
-func ParseCertificateToAttribute(ctx android.TopDownMutatorContext, certificate *string) (*string, *bazel.Label) {
-	var certificateLabel *bazel.Label
-	certificateName := proptools.StringDefault(certificate, "")
-	certModule := android.SrcIsModule(certificateName)
-	if certModule != "" {
-		c := android.BazelLabelForModuleDepSingle(ctx, certificateName)
-		certificateLabel = &c
-		certificate = nil
-	}
-	return certificate, certificateLabel
+	Certificate      bazel.LabelAttribute
+	Certificate_name bazel.StringAttribute
 }
 
 // ConvertWithBp2build is used to convert android_app to Bazel.
@@ -1513,7 +1499,8 @@
 
 	aapt := a.convertAaptAttrsWithBp2Build(ctx)
 
-	certificateName, certificate := ParseCertificateToAttribute(ctx, a.overridableAppProperties.Certificate)
+	certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate)
+
 	attrs := &bazelAndroidAppAttributes{
 		commonAttrs,
 		aapt,
diff --git a/java/fuzz.go b/java/fuzz.go
index 848d364..1d6b913 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -104,7 +104,9 @@
 		j.fuzzPackagedModule.Config = configPath
 	}
 
-	ctx.VisitDirectDepsWithTag(cc.JniFuzzLibTag, func(dep android.Module) {
+	_, sharedDeps := cc.CollectAllSharedDependencies(ctx)
+
+	for _, dep := range sharedDeps {
 		sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo)
 		if sharedLibInfo.SharedLibrary != nil {
 			// The .class jars are output in slightly different locations
@@ -127,7 +129,7 @@
 		} else {
 			ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
 		}
-	})
+	}
 
 	j.Library.GenerateAndroidBuildActions(ctx)
 }
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 0199d3a..17d80dd 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -30,7 +30,7 @@
 	defaultBindgenFlags = []string{""}
 
 	// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
-	bindgenClangVersion = "clang-r450784d"
+	bindgenClangVersion = "clang-r468909b"
 
 	_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
 		if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
@@ -51,7 +51,7 @@
 	})
 	_ = pctx.VariableFunc("bindgenClangLibdir", func(ctx android.PackageVarContext) string {
 		if ctx.Config().UseHostMusl() {
-			return "musl/lib64/"
+			return "musl/lib/"
 		} else {
 			return "lib64/"
 		}
@@ -239,6 +239,10 @@
 		cflags = append(cflags, "-x c")
 	}
 
+	// clang-r468909b complains about the -x c in the flags in clang-sys parse_search_paths:
+	// clang: error: '-x c' after last input file has no effect [-Werror,-Wunused-command-line-argument]
+	cflags = append(cflags, "-Wno-unused-command-line-argument")
+
 	// LLVM_NEXT may contain flags that bindgen doesn't recognise. Turn off unknown flags warning.
 	if ctx.Config().IsEnvTrue("LLVM_NEXT") {
 		cflags = append(cflags, "-Wno-unknown-warning-option")
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 76cf21a..6faf55c 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -91,7 +91,7 @@
 	out := fuzzer.binaryDecorator.compile(ctx, flags, deps)
 
 	// Grab the list of required shared libraries.
-	fuzzer.sharedLibraries = cc.CollectAllSharedDependencies(ctx)
+	fuzzer.sharedLibraries, _ = cc.CollectAllSharedDependencies(ctx)
 
 	return out
 }
diff --git a/scripts/microfactory.bash b/scripts/microfactory.bash
index 192b38f..ce4a0e4 100644
--- a/scripts/microfactory.bash
+++ b/scripts/microfactory.bash
@@ -59,7 +59,7 @@
     BUILDDIR=$(getoutdir) \
       SRCDIR=${TOP} \
       BLUEPRINTDIR=${TOP}/build/blueprint \
-      EXTRA_ARGS="-pkg-path android/soong=${TOP}/build/soong -pkg-path rbcrun=${TOP}/build/make/tools/rbcrun -pkg-path google.golang.org/protobuf=${TOP}/external/golang-protobuf -pkg-path go.starlark.net=${TOP}/external/starlark-go" \
+      EXTRA_ARGS="-pkg-path android/soong=${TOP}/build/soong -pkg-path prebuilts/bazel/common/proto=${TOP}/prebuilts/bazel/common/proto -pkg-path rbcrun=${TOP}/build/make/tools/rbcrun -pkg-path google.golang.org/protobuf=${TOP}/external/golang-protobuf -pkg-path go.starlark.net=${TOP}/external/starlark-go" \
       build_go $@
 }