Merge "Upload soong_build_metrics"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index fce8d7b..7134c7b 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -731,7 +731,7 @@
 		"platform_tools_properties", "build_tools_source_properties", // TODO(b/203369847): multiple genrules in the same package creating the same file
 
 		// aar support
-		"prebuilt_car-ui-androidx-core-common",         // TODO(b/224773339), genrule dependency creates an .aar, not a .jar
+		"prebuilt_car-ui-androidx-core-common", // TODO(b/224773339), genrule dependency creates an .aar, not a .jar
 		// ERROR: The dependencies for the following 1 jar(s) are not complete.
 		// 1.bazel-out/android_target-fastbuild/bin/prebuilts/tools/common/m2/_aar/robolectric-monitor-1.0.2-alpha1/classes_and_libs_merged.jar
 		"prebuilt_robolectric-monitor-1.0.2-alpha1",
@@ -1359,5 +1359,8 @@
 	// Staging-mode allowlist. Modules in this list are only built
 	// by Bazel with --bazel-mode-staging. This list should contain modules
 	// which will soon be added to the prod allowlist.
-	StagingMixedBuildsEnabledList = []string{"com.android.tzdata"}
+	StagingMixedBuildsEnabledList = []string{
+		"com.android.adbd",
+		"com.android.tzdata",
+	}
 )
diff --git a/apex/apex.go b/apex/apex.go
index 8e1783e..01e4f12 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -734,12 +734,14 @@
 	}
 }
 
-// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
-// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
-func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
-	deviceConfig := ctx.DeviceConfig()
+// getImageVariationPair returns a pair for the image variation name as its
+// prefix and suffix. The prefix indicates whether it's core/vendor/product and the
+// suffix indicates the vndk version when it's vendor or product.
+// getImageVariation can simply join the result of this function to get the
+// image variation name.
+func (a *apexBundle) getImageVariationPair(deviceConfig android.DeviceConfig) (string, string) {
 	if a.vndkApex {
-		return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
+		return cc.VendorVariationPrefix, a.vndkVersion(deviceConfig)
 	}
 
 	var prefix string
@@ -757,10 +759,17 @@
 		vndkVersion = deviceConfig.PlatformVndkVersion()
 	}
 	if vndkVersion != "" {
-		return prefix + vndkVersion
+		return prefix, vndkVersion
 	}
 
-	return android.CoreVariation // The usual case
+	return android.CoreVariation, "" // The usual case
+}
+
+// getImageVariation returns the image variant name for this apexBundle. In most cases, it's simply
+// android.CoreVariation, but gets complicated for the vendor APEXes and the VNDK APEX.
+func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
+	prefix, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig())
+	return prefix + vndkVersion
 }
 
 func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -3078,31 +3087,7 @@
 	// Module separator
 	//
 	m["com.android.btservices"] = []string{
-		"bluetooth-protos-lite",
-		"internal_include_headers",
-		"libaudio-a2dp-hw-utils",
-		"libaudio-hearing-aid-hw-utils",
-		"libbluetooth",
-		"libbluetooth-types",
-		"libbluetooth-types-header",
-		"libbluetooth_gd",
-		"libbluetooth_headers",
-		"libbluetooth_jni",
-		"libbt-audio-hal-interface",
-		"libbt-bta",
-		"libbt-common",
-		"libbt-hci",
-		"libbt-platform-protos-lite",
-		"libbt-protos-lite",
-		"libbt-sbc-decoder",
-		"libbt-sbc-encoder",
-		"libbt-stack",
-		"libbt-utils",
-		"libbtcore",
-		"libbtdevice",
-		"libbte",
-		"libbtif",
-		"libchrome",
+		// empty
 	}
 	//
 	// Module separator
diff --git a/apex/builder.go b/apex/builder.go
index 4be34d2..82a523c 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -235,6 +235,12 @@
 		optCommands = append(optCommands, "-a jniLibs "+strings.Join(jniLibs, " "))
 	}
 
+	if android.InList(":vndk", requireNativeLibs) {
+		if _, vndkVersion := a.getImageVariationPair(ctx.DeviceConfig()); vndkVersion != "" {
+			optCommands = append(optCommands, "-v vndkVersion "+vndkVersion)
+		}
+	}
+
 	manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json")
 	defaultVersion := android.DefaultUpdatableModuleVersion
 	if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
diff --git a/licenses/Android.bp b/licenses/Android.bp
index eabc303..7267cf3 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -921,6 +921,14 @@
 }
 
 license_kind {
+    name: "SPDX-license-identifier-Linux-syscall-note",
+    // expanding visibility requires approval from an OSPO lawyer or pcounsel
+    visibility: ["//external/libbpf:__subpackages__"],
+    conditions: ["permissive"],
+    url: "https://spdx.org/licenses/Linux-syscall-note.html",
+}
+
+license_kind {
     name: "SPDX-license-identifier-LPL-1.02",
     conditions: ["notice"],
     url: "https://spdx.org/licenses/LPL-1.02.html",
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index d89e6b7..7925ab0 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -17,11 +17,11 @@
 function test_null_build() {
   setup
   run_soong
-  local bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
-  local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
+  local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
   run_soong
-  local bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
-  local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
+  local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
 
   if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then
     # Bootstrapping is always done. It doesn't take a measurable amount of time.
@@ -36,12 +36,12 @@
 function test_soong_build_rebuilt_if_blueprint_changes() {
   setup
   run_soong
-  local mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
 
   sed -i 's/pluginGenSrcCmd/pluginGenSrcCmd2/g' build/blueprint/bootstrap/bootstrap.go
 
   run_soong
-  local mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
 
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Bootstrap Ninja file did not change"
@@ -79,7 +79,7 @@
 function test_add_android_bp() {
   setup
   run_soong
-  local mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   mkdir -p a
   cat > a/Android.bp <<'EOF'
@@ -91,7 +91,7 @@
   touch a/my_little_binary_host.py
   run_soong
 
-  local mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
@@ -142,7 +142,7 @@
 EOF
   touch a/my_little_binary_host.py
   run_soong
-  local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   local glob_deps_file=out/soong/globs/build/0.d
 
@@ -151,7 +151,7 @@
   fi
 
   run_soong
-  local ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
 
   # There is an ineffiencency in glob that requires bpglob to rerun once for each glob to update
   # the entry in the .ninja_log.  It doesn't update the output file, but we can detect the rerun
@@ -160,15 +160,15 @@
     fail "Glob deps file missing after second build"
   fi
 
-  local glob_deps_mtime2=$(stat -c "%y" "$glob_deps_file")
+  local -r glob_deps_mtime2=$(stat -c "%y" "$glob_deps_file")
 
   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
     fail "Ninja file rewritten on null incremental build"
   fi
 
   run_soong
-  local ninja_mtime3=$(stat -c "%y" out/soong/build.ninja)
-  local glob_deps_mtime3=$(stat -c "%y" "$glob_deps_file")
+  local -r ninja_mtime3=$(stat -c "%y" out/soong/build.ninja)
+  local -r glob_deps_mtime3=$(stat -c "%y" "$glob_deps_file")
 
   if [[ "$ninja_mtime2" != "$ninja_mtime3" ]]; then
     fail "Ninja file rewritten on null incremental build"
@@ -192,12 +192,12 @@
 EOF
   touch a/my_little_binary_host.py
   run_soong
-  local mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   touch a/my_little_library.py
   run_soong
 
-  local mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
@@ -275,10 +275,10 @@
   run_soong
   grep -q "CHERRY IS RED" out/soong/build.ninja \
     || fail "second value of environment variable not used"
-  local mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   run_soong
-  local mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$mtime1" != "$mtime2" ]]; then
     fail "Output Ninja file changed when environment variable did not"
   fi
@@ -288,7 +288,7 @@
 function test_create_global_include_directory() {
   setup
   run_soong
-  local mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   # Soong needs to know if top level directories like hardware/ exist for use
   # as global include directories.  Make sure that doesn't cause regens for
@@ -296,7 +296,7 @@
   mkdir -p system/core
 
   run_soong
-  local mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$mtime1" != "$mtime2" ]]; then
     fail "Output Ninja file changed when top level directory changed"
   fi
@@ -306,7 +306,7 @@
   mkdir -p system/core/include
 
   run_soong
-  local mtime3=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime3=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$mtime2" = "$mtime3" ]]; then
     fail "Output Ninja file did not change when global include directory created"
   fi
@@ -317,7 +317,7 @@
 function test_add_file_to_soong_build() {
   setup
   run_soong
-  local mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   mkdir -p a
   cat > a/Android.bp <<'EOF'
@@ -379,7 +379,7 @@
 EOF
 
   run_soong
-  local mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
@@ -457,7 +457,7 @@
 EOF
 
   run_soong
-  local mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   grep -q "Make it so" out/soong/build.ninja || fail "Original action not present"
 
@@ -489,7 +489,7 @@
 EOF
 
   run_soong
-  local mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$mtime1" == "$mtime2" ]]; then
     fail "Output Ninja file did not change"
   fi
@@ -514,20 +514,20 @@
   setup
 
   run_soong
-  local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   run_soong soong_docs
-  local docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html)
+  local -r docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html)
 
   run_soong soong_docs
-  local docs_mtime2=$(stat -c "%y" out/soong/docs/soong_build.html)
+  local -r docs_mtime2=$(stat -c "%y" out/soong/docs/soong_build.html)
 
   if [[ "$docs_mtime1" != "$docs_mtime2" ]]; then
     fail "Output Ninja file changed on null build"
   fi
 
   run_soong
-  local ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
 
   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
     fail "Output Ninja file changed on null build"
@@ -552,7 +552,7 @@
   run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=false ${EXPECTED_OUT} &> /dev/null && \
     fail "Write to source tree should not work in a ReadOnly source tree"
 
-  if grep -q "${ERROR_MSG}" ${ERROR_LOG} && grep -q "${ERROR_HINT_PATTERN}" ${ERROR_LOG} ; then
+  if grep -q "${ERROR_MSG}" "${ERROR_LOG}" && grep -q "${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then
     echo Error message and error hint found in logs >/dev/null
   else
     fail "Did not find Read-only error AND error hint in error.log"
@@ -562,7 +562,7 @@
   run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true ${EXPECTED_OUT} &> /dev/null || \
     fail "Write to source tree did not succeed in a ReadWrite source tree"
 
-  if  grep -q "${ERROR_MSG}\|${ERROR_HINT_PATTERN}" ${ERROR_LOG} ; then
+  if  grep -q "${ERROR_MSG}\|${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then
     fail "Found read-only error OR error hint in error.log"
   fi
 }
@@ -606,11 +606,11 @@
     fail "BUILD file in symlink forest was not created";
   fi
 
-  local mtime1=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
+  local -r mtime1=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
 
   touch a/irrelevant.txt
   run_soong bp2build
-  local mtime2=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
+  local -r mtime2=$(stat -c "%y" out/soong/bp2build/a/b/BUILD.bazel)
 
   if [[ "$mtime1" != "$mtime2" ]]; then
     fail "BUILD.bazel file was regenerated"
@@ -657,10 +657,10 @@
   setup
 
   run_soong bp2build
-  local mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+  local -r mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
 
   run_soong bp2build
-  local mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+  local -r mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
 
   if [[ "$mtime1" != "$mtime2" ]]; then
     fail "Output Ninja file changed on null build"
@@ -717,19 +717,19 @@
   setup
 
   run_soong
-  local ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   run_soong json-module-graph
-  local json_mtime1=$(stat -c "%y" out/soong/module-graph.json)
+  local -r json_mtime1=$(stat -c "%y" out/soong/module-graph.json)
 
   run_soong
-  local ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r ninja_mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
     fail "Output Ninja file changed after writing JSON module graph"
   fi
 
   run_soong json-module-graph
-  local json_mtime2=$(stat -c "%y" out/soong/module-graph.json)
+  local -r json_mtime2=$(stat -c "%y" out/soong/module-graph.json)
   if [[ "$json_mtime1" != "$json_mtime2" ]]; then
     fail "JSON module graph file changed after writing Ninja file"
   fi
@@ -837,19 +837,19 @@
   setup
 
   run_soong
-  local output_mtime1=$(stat -c "%y" out/soong/build.ninja)
+  local -r output_mtime1=$(stat -c "%y" out/soong/build.ninja)
 
   run_soong bp2build
-  local output_mtime2=$(stat -c "%y" out/soong/build.ninja)
+  local -r output_mtime2=$(stat -c "%y" out/soong/build.ninja)
   if [[ "$output_mtime1" != "$output_mtime2" ]]; then
     fail "Output Ninja file changed when switching to bp2build"
   fi
 
-  local marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+  local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
 
   run_soong
-  local output_mtime3=$(stat -c "%y" out/soong/build.ninja)
-  local marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+  local -r output_mtime3=$(stat -c "%y" out/soong/build.ninja)
+  local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
   if [[ "$output_mtime1" != "$output_mtime3" ]]; then
     fail "Output Ninja file changed when switching to regular build from bp2build"
   fi
@@ -858,8 +858,8 @@
   fi
 
   run_soong bp2build
-  local output_mtime4=$(stat -c "%y" out/soong/build.ninja)
-  local marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+  local -r output_mtime4=$(stat -c "%y" out/soong/build.ninja)
+  local -r marker_mtime3=$(stat -c "%y" out/soong/bp2build_workspace_marker)
   if [[ "$output_mtime1" != "$output_mtime4" ]]; then
     fail "Output Ninja file changed when switching back to bp2build"
   fi
@@ -880,10 +880,10 @@
   setup
 
   run_soong queryview
-  local output_mtime1=$(stat -c "%y" out/soong/queryview.marker)
+  local -r output_mtime1=$(stat -c "%y" out/soong/queryview.marker)
 
   run_soong queryview
-  local output_mtime2=$(stat -c "%y" out/soong/queryview.marker)
+  local -r output_mtime2=$(stat -c "%y" out/soong/queryview.marker)
 
   if [[ "$output_mtime1" != "$output_mtime2" ]]; then
     fail "Queryview marker file changed on null build"