Merge "VSDK: etc snapshot may have sub_dir for relative_install_path" into udc-dev
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index e3e4dba..63d4e11 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -59,7 +59,9 @@
 
 		"build/bazel":                        Bp2BuildDefaultTrueRecursively,
 		"build/make/target/product/security": Bp2BuildDefaultTrue,
+		"build/make/tools/protos":            Bp2BuildDefaultTrue,
 		"build/make/tools/releasetools":      Bp2BuildDefaultTrue,
+		"build/make/tools/sbom":              Bp2BuildDefaultTrue,
 		"build/make/tools/signapk":           Bp2BuildDefaultTrue,
 		"build/make/tools/zipalign":          Bp2BuildDefaultTrueRecursively,
 		"build/soong":                        Bp2BuildDefaultTrue,
@@ -1427,6 +1429,9 @@
 		"styleprotoslite",
 		"CtsPkgInstallerConstants",
 		"guava-android-testlib",
+
+		// python_test_host with test data
+		"sbom_writers_test",
 	}
 
 	MixedBuildsDisabledList = []string{
diff --git a/android/filegroup.go b/android/filegroup.go
index 0ca5dc5..f30ee51 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -75,7 +75,8 @@
 
 // https://docs.bazel.build/versions/master/be/general.html#filegroup
 type bazelFilegroupAttributes struct {
-	Srcs bazel.LabelListAttribute
+	Srcs                bazel.LabelListAttribute
+	Applicable_licenses bazel.LabelListAttribute
 }
 
 type bazelAidlLibraryAttributes struct {
diff --git a/android/package.go b/android/package.go
index 2bf6521..7fbc700 100644
--- a/android/package.go
+++ b/android/package.go
@@ -15,6 +15,8 @@
 package android
 
 import (
+	"path/filepath"
+
 	"android/soong/bazel"
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -39,8 +41,8 @@
 }
 
 type bazelPackageAttributes struct {
-	Default_visibility          []string
-	Default_applicable_licenses bazel.LabelListAttribute
+	Default_visibility       []string
+	Default_package_metadata bazel.LabelListAttribute
 }
 
 type packageModule struct {
@@ -53,13 +55,32 @@
 var _ Bazelable = &packageModule{}
 
 func (p *packageModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
+	defaultPackageMetadata := bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, p.properties.Default_applicable_licenses))
+	// If METADATA file exists in the package, add it to package(default_package_metadata=) using a
+	// filegroup(name="default_metadata_file") which can be accessed later on each module in Bazel
+	// using attribute "applicable_licenses".
+	// Attribute applicable_licenses of filegroup "default_metadata_file" has to be set to [],
+	// otherwise Bazel reports cyclic reference error.
+	if existed, _, _ := ctx.Config().fs.Exists(filepath.Join(ctx.ModuleDir(), "METADATA")); existed {
+		ctx.CreateBazelTargetModule(
+			bazel.BazelTargetModuleProperties{
+				Rule_class: "filegroup",
+			},
+			CommonAttributes{Name: "default_metadata_file"},
+			&bazelFilegroupAttributes{
+				Srcs:                bazel.MakeLabelListAttribute(BazelLabelForModuleSrc(ctx, []string{"METADATA"})),
+				Applicable_licenses: bazel.LabelListAttribute{Value: bazel.LabelList{Includes: []bazel.Label{}}, EmitEmptyList: true},
+			})
+		defaultPackageMetadata.Value.Add(&bazel.Label{Label: ":default_metadata_file"})
+	}
+
 	ctx.CreateBazelTargetModule(
 		bazel.BazelTargetModuleProperties{
 			Rule_class: "package",
 		},
 		CommonAttributes{},
 		&bazelPackageAttributes{
-			Default_applicable_licenses: bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, p.properties.Default_applicable_licenses)),
+			Default_package_metadata: defaultPackageMetadata,
 			// FIXME(asmundak): once b/221436821 is resolved
 			Default_visibility: []string{"//visibility:public"},
 		})
diff --git a/android/util.go b/android/util.go
index 38e0a4d..20d007d 100644
--- a/android/util.go
+++ b/android/util.go
@@ -26,7 +26,11 @@
 
 // CopyOf returns a new slice that has the same contents as s.
 func CopyOf(s []string) []string {
-	return append([]string(nil), s...)
+	// If the input is nil, return nil and not an empty list
+	if s == nil {
+		return s
+	}
+	return append([]string{}, s...)
 }
 
 // Concat returns a new slice concatenated from the two input slices. It does not change the input
diff --git a/android/util_test.go b/android/util_test.go
index 5584b38..a2ef589 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -381,6 +381,14 @@
 	}
 }
 
+func TestCopyOfEmptyAndNil(t *testing.T) {
+	emptyList := []string{}
+	copyOfEmptyList := CopyOf(emptyList)
+	AssertBoolEquals(t, "Copy of an empty list should be an empty list and not nil", true, copyOfEmptyList != nil)
+	copyOfNilList := CopyOf(nil)
+	AssertBoolEquals(t, "Copy of a nil list should be a nil list and not an empty list", true, copyOfNilList == nil)
+}
+
 func ExampleCopyOf() {
 	a := []string{"1", "2", "3"}
 	b := CopyOf(a)
diff --git a/android/variable.go b/android/variable.go
index 496f523..aaf0606 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -469,6 +469,10 @@
 	SourceRootDirs []string `json:",omitempty"`
 
 	AfdoProfiles []string `json:",omitempty"`
+
+	ProductManufacturer string   `json:",omitempty"`
+	ProductBrand        string   `json:",omitempty"`
+	BuildVersionTags    []string `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 7fb6f50..c1c9e5c 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -137,6 +137,10 @@
 	// List of filesystem images that are embedded inside this APEX bundle.
 	Filesystems []string
 
+	// The minimum SDK version that this APEX must support at minimum. This is usually set to
+	// the SDK version that the APEX was first introduced.
+	Min_sdk_version *string
+
 	// Whether this APEX is considered updatable or not. When set to true, this will enforce
 	// additional rules for making sure that the APEX is truly updatable. To be updatable,
 	// min_sdk_version should be set as well. This will also disable the size optimizations like
@@ -380,10 +384,6 @@
 
 	// Trim against a specific Dynamic Common Lib APEX
 	Trim_against *string
-
-	// The minimum SDK version that this APEX must support at minimum. This is usually set to
-	// the SDK version that the APEX was first introduced.
-	Min_sdk_version *string
 }
 
 type apexBundle struct {
@@ -2924,7 +2924,7 @@
 	// Only override the minSdkVersion value on Apexes which already specify
 	// a min_sdk_version (it's optional for non-updatable apexes), and that its
 	// min_sdk_version value is lower than the one to override with.
-	minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.overridableProperties.Min_sdk_version))
+	minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
 	if minApiLevel.IsNone() {
 		return ""
 	}
@@ -3575,8 +3575,8 @@
 	// TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
 	// given it's coming via config, we probably don't want to put it in here.
 	var minSdkVersion bazel.StringAttribute
-	if a.overridableProperties.Min_sdk_version != nil {
-		minSdkVersion.SetValue(*a.overridableProperties.Min_sdk_version)
+	if a.properties.Min_sdk_version != nil {
+		minSdkVersion.SetValue(*a.properties.Min_sdk_version)
 	}
 	if props, ok := productVariableProps[minSdkVersionPropName]; ok {
 		for c, p := range props {
diff --git a/bp2build/package_conversion_test.go b/bp2build/package_conversion_test.go
index 3704b2d..ce848e4 100644
--- a/bp2build/package_conversion_test.go
+++ b/bp2build/package_conversion_test.go
@@ -15,9 +15,10 @@
 package bp2build
 
 import (
+	"testing"
+
 	"android/soong/android"
 	"android/soong/genrule"
-	"testing"
 )
 
 func registerDependentModules(ctx android.RegistrationContext) {
@@ -29,6 +30,7 @@
 	tests := []struct {
 		description string
 		modules     string
+		fs          map[string]string
 		expected    []ExpectedRuleTarget
 	}{
 		{
@@ -50,8 +52,8 @@
 					"package",
 					"",
 					AttrNameToString{
-						"default_applicable_licenses": `[":my_license"]`,
-						"default_visibility":          `["//visibility:public"]`,
+						"default_package_metadata": `[":my_license"]`,
+						"default_visibility":       `["//visibility:public"]`,
 					},
 					android.HostAndDeviceDefault,
 				},
@@ -67,6 +69,57 @@
 				},
 			},
 		},
+		{
+			description: "package has METADATA file",
+			fs: map[string]string{
+				"METADATA": ``,
+			},
+			modules: `
+license {
+  name: "my_license",
+  visibility: [":__subpackages__"],
+  license_kinds: ["SPDX-license-identifier-Apache-2.0"],
+  license_text: ["NOTICE"],
+}
+
+package {
+  default_applicable_licenses: ["my_license"],
+}
+`,
+			expected: []ExpectedRuleTarget{
+				{
+					"package",
+					"",
+					AttrNameToString{
+						"default_package_metadata": `[
+        ":my_license",
+        ":default_metadata_file",
+    ]`,
+						"default_visibility": `["//visibility:public"]`,
+					},
+					android.HostAndDeviceDefault,
+				},
+				{
+					"android_license",
+					"my_license",
+					AttrNameToString{
+						"license_kinds": `["SPDX-license-identifier-Apache-2.0"]`,
+						"license_text":  `"NOTICE"`,
+						"visibility":    `[":__subpackages__"]`,
+					},
+					android.HostAndDeviceDefault,
+				},
+				{
+					"filegroup",
+					"default_metadata_file",
+					AttrNameToString{
+						"applicable_licenses": `[]`,
+						"srcs":                `["METADATA"]`,
+					},
+					android.HostAndDeviceDefault,
+				},
+			},
+		},
 	}
 	for _, test := range tests {
 		expected := make([]string, 0, len(test.expected))
@@ -80,6 +133,7 @@
 				ModuleTypeUnderTestFactory: android.PackageFactory,
 				Blueprint:                  test.modules,
 				ExpectedBazelTargets:       expected,
+				Filesystem:                 test.fs,
 			})
 	}
 }
diff --git a/cc/config/global.go b/cc/config/global.go
index 3df739e..a0fe4b7 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -111,9 +111,6 @@
 
 		// Turn off FMA which got enabled by default in clang-r445002 (http://b/218805949)
 		"-ffp-contract=off",
-
-		// Turn off stack protector check for noreturn calls. (http://b/264965700)
-		"-mllvm -disable-check-noreturn-call",
 	}
 
 	commonGlobalConlyflags = []string{}
@@ -150,9 +147,6 @@
 	commonGlobalLldflags = []string{
 		"-fuse-ld=lld",
 		"-Wl,--icf=safe",
-
-		// Turn off stack protector check for noreturn calls. (http://b/264965700)
-		"-Wl,-mllvm,-disable-check-noreturn-call",
 	}
 
 	deviceGlobalCppflags = []string{
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 79a5ce4..2c35d76 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -443,10 +443,16 @@
 		}
 		writeMetrics(configuration, ctx.EventHandler, metricsDir)
 	}
-	writeUsedEnvironmentFile(configuration, finalOutputFile)
+	writeUsedEnvironmentFile(configuration)
+
+	// Touch the output file so that it's the newest file created by soong_build.
+	// This is necessary because, if soong_build generated any files which
+	// are ninja inputs to the main output file, then ninja would superfluously
+	// rebuild this output file on the next build invocation.
+	touch(shared.JoinPath(topDir, finalOutputFile))
 }
 
-func writeUsedEnvironmentFile(configuration android.Config, finalOutputFile string) {
+func writeUsedEnvironmentFile(configuration android.Config) {
 	if usedEnvFile == "" {
 		return
 	}
@@ -465,11 +471,6 @@
 	}
 	err = os.WriteFile(path, data, 0666)
 	maybeQuit(err, "error writing used environment file '%s'", usedEnvFile)
-
-	// Touch the output file so that it's not older than the file we just
-	// wrote. We can't write the environment file earlier because one an access
-	// new environment variables while writing it.
-	touch(shared.JoinPath(topDir, finalOutputFile))
 }
 
 func touch(path string) {
diff --git a/java/app.go b/java/app.go
index 03e2330..706f99a 100755
--- a/java/app.go
+++ b/java/app.go
@@ -563,19 +563,6 @@
 		certificates = append([]Certificate{mainCert}, certificates...)
 	}
 
-	if !m.Platform() {
-		certPath := certificates[0].Pem.String()
-		systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
-		if strings.HasPrefix(certPath, systemCertPath) {
-			enforceSystemCert := ctx.Config().EnforceSystemCertificate()
-			allowed := ctx.Config().EnforceSystemCertificateAllowList()
-
-			if enforceSystemCert && !inList(m.Name(), allowed) {
-				ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
-			}
-		}
-	}
-
 	if len(certificates) > 0 {
 		mainCertificate = certificates[0]
 	} else {
@@ -591,6 +578,20 @@
 		}
 	}
 
+	if !m.Platform() {
+		certPath := mainCertificate.Pem.String()
+		systemCertPath := ctx.Config().DefaultAppCertificateDir(ctx).String()
+		if strings.HasPrefix(certPath, systemCertPath) {
+			enforceSystemCert := ctx.Config().EnforceSystemCertificate()
+			allowed := ctx.Config().EnforceSystemCertificateAllowList()
+
+			if enforceSystemCert && !inList(m.Name(), allowed) {
+				ctx.PropertyErrorf("certificate", "The module in product partition cannot be signed with certificate in system.")
+			}
+		}
+	}
+
+
 	return mainCertificate, certificates
 }
 
diff --git a/java/app_test.go b/java/app_test.go
index 7e97b0f..b154bc9 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3382,6 +3382,14 @@
 			srcs: ["a.java"],
 			certificate: ":missing_certificate",
 			sdk_version: "current",
+		}
+
+		android_app {
+			name: "bar",
+			srcs: ["a.java"],
+			certificate: ":missing_certificate",
+			product_specific: true,
+			sdk_version: "current",
 		}`)
 
 	foo := result.ModuleForTests("foo", "android_common")
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 13fa81e..96645b0 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -29,7 +29,7 @@
 	defaultBindgenFlags = []string{""}
 
 	// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
-	bindgenClangVersion = "clang-r487747"
+	bindgenClangVersion = "clang-r487747c"
 
 	_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
 		if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index fda5ca0..5935247 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -885,4 +885,37 @@
   fi
 }
 
+# This test verifies that adding a new glob to a blueprint file only
+# causes build.ninja to be regenerated on the *next* build, and *not*
+# the build after. (This is a regression test for a bug where globs
+# resulted in two successive regenerations.)
+function test_new_glob_incrementality {
+  setup
+
+  run_soong nothing
+  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+  mkdir -p globdefpkg/
+  cat > globdefpkg/Android.bp <<'EOF'
+filegroup {
+  name: "fg_with_glob",
+  srcs: ["*.txt"],
+}
+EOF
+
+  run_soong nothing
+  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
+
+  if [[ "$mtime1" == "$mtime2" ]]; then
+    fail "Ninja file was not regenerated, despite a new bp file"
+  fi
+
+  run_soong nothing
+  local -r mtime3=$(stat -c "%y" out/soong/build.ninja)
+
+  if [[ "$mtime2" != "$mtime3" ]]; then
+    fail "Ninja file was regenerated despite no previous bp changes"
+  fi
+}
+
 scan_and_run_tests
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 3f628cf..62079fe 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -87,6 +87,8 @@
 			"TEST_MAPPING",
 			// Bazel top-level file to mark a directory as a Bazel workspace.
 			"WORKSPACE",
+			// METADATA file of packages
+			"METADATA",
 		},
 		// Bazel Starlark configuration files and all .mk files for product/board configuration.
 		IncludeSuffixes: []string{".bzl", ".mk"},
@@ -189,6 +191,13 @@
 		ctx.Fatalf("Could not find OWNERS: %v", err)
 	}
 
+	// Recursively look for all METADATA files.
+	metadataFiles := f.FindNamedAt(".", "METADATA")
+	err = dumpListToFile(ctx, config, metadataFiles, filepath.Join(dumpDir, "METADATA.list"))
+	if err != nil {
+		ctx.Fatalf("Could not find METADATA: %v", err)
+	}
+
 	// Recursively look for all TEST_MAPPING files.
 	testMappings := f.FindNamedAt(".", "TEST_MAPPING")
 	err = dumpListToFile(ctx, config, testMappings, filepath.Join(dumpDir, "TEST_MAPPING.list"))
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 9287731..8ead4c9 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -397,6 +397,8 @@
 			pbi.Inputs = append(pbi.Inputs,
 				config.Bp2BuildFilesMarkerFile(),
 				filepath.Join(config.FileListDir(), "bazel.list"))
+		case bp2buildFilesTag:
+			pbi.Inputs = append(pbi.Inputs, filepath.Join(config.FileListDir(), "METADATA.list"))
 		}
 		invocations = append(invocations, pbi)
 	}