Merge "Process bazel metrics prior to potentially exiting upload.go"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 6bd4e26..433c063 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -195,6 +195,8 @@
 		"frameworks/av/media/audioaidlconversion":            Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/codec2/components/aom":          Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/codecs":                         Bp2BuildDefaultTrueRecursively,
+		"frameworks/av/media/module/codecs":                  Bp2BuildDefaultTrueRecursively,
+		"frameworks/av/media/module/foundation":              Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/liberror":                       Bp2BuildDefaultTrueRecursively,
 		"frameworks/av/media/libmediahelper":                 Bp2BuildDefaultTrue,
 		"frameworks/av/media/libshmem":                       Bp2BuildDefaultTrueRecursively,
@@ -450,7 +452,6 @@
 		"code_coverage.policy",
 		"code_coverage.policy.other",
 		"codec2_soft_exports",
-		"codecs_g711dec",
 		"com.android.media.swcodec",
 		"com.android.media.swcodec-androidManifest",
 		"com.android.media.swcodec-ld.config.txt",
@@ -495,20 +496,6 @@
 		"libandroidio",
 		"libandroidio_srcs",
 		"libserviceutils",
-		"libstagefright_amrnbenc",
-		"libstagefright_amrnbdec",
-		"libstagefright_amrwbdec",
-		"libstagefright_amrwbenc",
-		"libstagefright_amrnb_common",
-		"libstagefright_enc_common",
-		"libstagefright_flacdec",
-		"libstagefright_foundation",
-		"libstagefright_foundation_headers",
-		"libstagefright_headers",
-		"libstagefright_m4vh263dec",
-		"libstagefright_m4vh263enc",
-		"libstagefright_mp3dec",
-		"libstagefright_mp3dec_headers",
 		"libsurfaceflinger_headers",
 		"libsync",
 		"libtextclassifier_hash_headers",
@@ -747,6 +734,8 @@
 
 		// Mainline Module Apps
 		"CaptivePortalLogin",
+
+		"libstagefright_headers",
 	}
 
 	Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -958,13 +947,11 @@
 
 		// cc_test with unconverted deps, or are device-only (and not verified to pass yet)
 		"AMRWBEncTest",
-		"AmrnbDecoderTest",     // depends on unconverted modules: libaudioutils, libsndfile
-		"AmrnbEncoderTest",     // depends on unconverted modules: libaudioutils, libsndfile
-		"AmrwbDecoderTest",     // depends on unconverted modules: libsndfile, libaudioutils
-		"AmrwbEncoderTest",     // depends on unconverted modules: libaudioutils, libsndfile
-		"Mp3DecoderTest",       // depends on unconverted modules: libsndfile, libaudioutils
-		"Mpeg4H263DecoderTest", // depends on unconverted modules: libstagefright_foundation
-		"Mpeg4H263EncoderTest",
+		"AmrnbDecoderTest", // depends on unconverted modules: libaudioutils, libsndfile
+		"AmrnbEncoderTest", // depends on unconverted modules: libaudioutils, libsndfile
+		"AmrwbDecoderTest", // depends on unconverted modules: libsndfile, libaudioutils
+		"AmrwbEncoderTest", // depends on unconverted modules: libaudioutils, libsndfile
+		"Mp3DecoderTest",   // depends on unconverted modules: libsndfile, libaudioutils
 		"avcdec",
 		"avcenc",
 		"bionic-benchmarks-tests",
@@ -1444,6 +1431,10 @@
 		"styleprotoslite",
 		"CtsPkgInstallerConstants",
 		"guava-android-testlib",
+
+		"MetaDataBaseUnitTest", // depends on libstagefright
+		"AVCUtilsUnitTest",     // depends on libstagefright
+		"ColorUtilsTest",       // depends on libmediandk
 	}
 
 	MixedBuildsDisabledList = []string{
@@ -1545,7 +1536,15 @@
 	// which will soon be added to the prod allowlist.
 	// It is implicit that all modules in ProdMixedBuildsEnabledList will
 	// also be built - do not add them to this list.
-	StagingMixedBuildsEnabledList = []string{}
+	StagingMixedBuildsEnabledList = []string{
+		// M13: media.swcodec launch
+		"com.android.media.swcodec",
+		"test_com.android.media.swcodec",
+		"libstagefright_foundation",
+		"libcodec2_hidl@1.0",
+		"libcodec2_hidl@1.1",
+		"libcodec2_hidl@1.2",
+	}
 
 	// These should be the libs that are included by the apexes in the ProdMixedBuildsEnabledList
 	ProdDclaMixedBuildsEnabledList = []string{
diff --git a/android/api_levels.go b/android/api_levels.go
index 7214ccb..fa919fd 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -15,12 +15,10 @@
 package android
 
 import (
+	"android/soong/starlark_import"
 	"encoding/json"
 	"fmt"
 	"strconv"
-
-	"android/soong/bazel"
-	"android/soong/starlark_fmt"
 )
 
 func init() {
@@ -288,13 +286,17 @@
 // ReplaceFinalizedCodenames returns the API level number associated with that API level
 // if the `raw` input is the codename of an API level has been finalized.
 // If the input is *not* a finalized codename, the input is returned unmodified.
-func ReplaceFinalizedCodenames(config Config, raw string) string {
-	num, ok := getFinalCodenamesMap(config)[raw]
+func ReplaceFinalizedCodenames(config Config, raw string) (string, error) {
+	finalCodenamesMap, err := getFinalCodenamesMap(config)
+	if err != nil {
+		return raw, err
+	}
+	num, ok := finalCodenamesMap[raw]
 	if !ok {
-		return raw
+		return raw, nil
 	}
 
-	return strconv.Itoa(num)
+	return strconv.Itoa(num), nil
 }
 
 // ApiLevelFrom converts the given string `raw` to an ApiLevel.
@@ -344,7 +346,11 @@
 		}
 	}
 
-	canonical, ok := getApiLevelsMapReleasedVersions()[raw]
+	apiLevelsReleasedVersions, err := getApiLevelsMapReleasedVersions()
+	if err != nil {
+		return NoneApiLevel, err
+	}
+	canonical, ok := apiLevelsReleasedVersions[raw]
 	if !ok {
 		asInt, err := strconv.Atoi(raw)
 		if err != nil {
@@ -410,37 +416,21 @@
 	return PathForOutput(ctx, "api_levels.json")
 }
 
-func getApiLevelsMapReleasedVersions() map[string]int {
-	return map[string]int{
-		"G":        9,
-		"I":        14,
-		"J":        16,
-		"J-MR1":    17,
-		"J-MR2":    18,
-		"K":        19,
-		"L":        21,
-		"L-MR1":    22,
-		"M":        23,
-		"N":        24,
-		"N-MR1":    25,
-		"O":        26,
-		"O-MR1":    27,
-		"P":        28,
-		"Q":        29,
-		"R":        30,
-		"S":        31,
-		"S-V2":     32,
-		"Tiramisu": 33,
-	}
+func getApiLevelsMapReleasedVersions() (map[string]int, error) {
+	return starlark_import.GetStarlarkValue[map[string]int]("api_levels_released_versions")
 }
 
 var finalCodenamesMapKey = NewOnceKey("FinalCodenamesMap")
 
-func getFinalCodenamesMap(config Config) map[string]int {
+func getFinalCodenamesMap(config Config) (map[string]int, error) {
+	type resultStruct struct {
+		result map[string]int
+		err    error
+	}
 	// This logic is replicated in starlark, if changing logic here update starlark code too
 	// https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/common/api.bzl;l=30;drc=231c7e8c8038fd478a79eb68aa5b9f5c64e0e061
-	return config.Once(finalCodenamesMapKey, func() interface{} {
-		apiLevelsMap := getApiLevelsMapReleasedVersions()
+	result := config.Once(finalCodenamesMapKey, func() interface{} {
+		apiLevelsMap, err := getApiLevelsMapReleasedVersions()
 
 		// TODO: Differentiate "current" and "future".
 		// The code base calls it FutureApiLevel, but the spelling is "current",
@@ -453,41 +443,44 @@
 		// added in S, both of these are usable when building for "current" when
 		// neither R nor S are final, but the S APIs stop being available in a
 		// final R build.
-		if Bool(config.productVariables.Platform_sdk_final) {
+		if err == nil && Bool(config.productVariables.Platform_sdk_final) {
 			apiLevelsMap["current"] = config.PlatformSdkVersion().FinalOrFutureInt()
 		}
 
-		return apiLevelsMap
-	}).(map[string]int)
+		return resultStruct{apiLevelsMap, err}
+	}).(resultStruct)
+	return result.result, result.err
 }
 
 var apiLevelsMapKey = NewOnceKey("ApiLevelsMap")
 
 // ApiLevelsMap has entries for preview API levels
-func GetApiLevelsMap(config Config) map[string]int {
+func GetApiLevelsMap(config Config) (map[string]int, error) {
+	type resultStruct struct {
+		result map[string]int
+		err    error
+	}
 	// This logic is replicated in starlark, if changing logic here update starlark code too
 	// https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/common/api.bzl;l=23;drc=231c7e8c8038fd478a79eb68aa5b9f5c64e0e061
-	return config.Once(apiLevelsMapKey, func() interface{} {
-		apiLevelsMap := getApiLevelsMapReleasedVersions()
-		for i, codename := range config.PlatformVersionAllPreviewCodenames() {
-			apiLevelsMap[codename] = previewAPILevelBase + i
+	result := config.Once(apiLevelsMapKey, func() interface{} {
+		apiLevelsMap, err := getApiLevelsMapReleasedVersions()
+		if err == nil {
+			for i, codename := range config.PlatformVersionAllPreviewCodenames() {
+				apiLevelsMap[codename] = previewAPILevelBase + i
+			}
 		}
 
-		return apiLevelsMap
-	}).(map[string]int)
+		return resultStruct{apiLevelsMap, err}
+	}).(resultStruct)
+	return result.result, result.err
 }
 
 func (a *apiLevelsSingleton) GenerateBuildActions(ctx SingletonContext) {
-	apiLevelsMap := GetApiLevelsMap(ctx.Config())
+	apiLevelsMap, err := GetApiLevelsMap(ctx.Config())
+	if err != nil {
+		ctx.Errorf("%s\n", err)
+		return
+	}
 	apiLevelsJson := GetApiLevelsJson(ctx)
 	createApiLevelsJson(ctx, apiLevelsJson, apiLevelsMap)
 }
-
-func StarlarkApiLevelConfigs(config Config) string {
-	return fmt.Sprintf(bazel.GeneratedBazelFileWarning+`
-_api_levels_released_versions = %s
-
-api_levels_released_versions = _api_levels_released_versions
-`, starlark_fmt.PrintStringIntDict(getApiLevelsMapReleasedVersions(), 0),
-	)
-}
diff --git a/android/config.go b/android/config.go
index 0b54ed9..5265374 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1929,6 +1929,10 @@
 	return c.mixedBuildEnabledModules
 }
 
+func (c *config) GetMixedBuildsDisabledModules() map[string]struct{} {
+	return c.mixedBuildDisabledModules
+}
+
 func (c *config) LogMixedBuild(ctx BaseModuleContext, useBazel bool) {
 	moduleName := ctx.Module().Name()
 	c.mixedBuildsLock.Lock()
diff --git a/android/sdk.go b/android/sdk.go
index 63e0bbe..6b598ab 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -830,6 +830,9 @@
 	// IsTargetBuildBeforeTiramisu return true if the target build release for which this snapshot is
 	// being generated is before Tiramisu, i.e. S.
 	IsTargetBuildBeforeTiramisu() bool
+
+	// ModuleErrorf reports an error at the line number of the module type in the module definition.
+	ModuleErrorf(fmt string, args ...interface{})
 }
 
 // ExportedComponentsInfo contains information about the components that this module exports to an
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 9f78195..776129f 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -153,10 +153,10 @@
         "//build/bazel/platforms/os:linux_glibc": ["linux.cpp"],
         "//conditions:default": [],
     })`,
-			"sdk_version":                       `"current"`,
-			"min_sdk_version":                   `"29"`,
-			"use_version_lib":                   `True`,
-			"implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
+			"sdk_version":        `"current"`,
+			"min_sdk_version":    `"29"`,
+			"use_version_lib":    `True`,
+			"whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
 		}),
 	})
 }
@@ -4483,3 +4483,43 @@
 		},
 	})
 }
+
+func TestCcLibraryCppFlagsInProductVariables(t *testing.T) {
+	runCcLibraryTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library cppflags in product variables",
+		ModuleTypeUnderTest:        "cc_library",
+		ModuleTypeUnderTestFactory: cc.LibraryFactory,
+		Blueprint: soongCcLibraryPreamble + `cc_library {
+    name: "a",
+    srcs: ["a.cpp"],
+    cppflags: [
+        "-Wextra",
+        "-DDEBUG_ONLY_CODE=0",
+    ],
+    product_variables: {
+        eng: {
+            cppflags: [
+                "-UDEBUG_ONLY_CODE",
+                "-DDEBUG_ONLY_CODE=1",
+            ],
+        },
+    },
+    include_build_directory: false,
+}
+`,
+		ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
+			"cppflags": `[
+        "-Wextra",
+        "-DDEBUG_ONLY_CODE=0",
+    ] + select({
+        "//build/bazel/product_variables:eng": [
+            "-UDEBUG_ONLY_CODE",
+            "-DDEBUG_ONLY_CODE=1",
+        ],
+        "//conditions:default": [],
+    })`,
+			"srcs": `["a.cpp"]`,
+		}),
+	},
+	)
+}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index f5d62c6..47dff8a 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -516,8 +516,8 @@
 }`,
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
-				"use_version_lib":                   "True",
-				"implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
+				"use_version_lib":    "True",
+				"whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
 			}),
 		},
 	})
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index f89f2dd..9488014 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1613,7 +1613,7 @@
 }`,
 		ExpectedBazelTargets: []string{
 			MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
-				"implementation_whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
+				"whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
 			}),
 		},
 	})
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 608fcd8..f598332 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -59,14 +59,17 @@
 
 	files = append(files, newFile("product_config", "arch_configuration.bzl", android.StarlarkArchConfigurations()))
 
-	apiLevelsContent, err := json.Marshal(android.GetApiLevelsMap(cfg))
+	apiLevelsMap, err := android.GetApiLevelsMap(cfg)
+	if err != nil {
+		return nil, err
+	}
+	apiLevelsContent, err := json.Marshal(apiLevelsMap)
 	if err != nil {
 		return nil, err
 	}
 	files = append(files, newFile("api_levels", GeneratedBuildFileName, `exports_files(["api_levels.json"])`))
 	// TODO(b/269691302)  value of apiLevelsContent is product variable dependent and should be avoided for soong injection
 	files = append(files, newFile("api_levels", "api_levels.json", string(apiLevelsContent)))
-	files = append(files, newFile("api_levels", "api_levels.bzl", android.StarlarkApiLevelConfigs(cfg)))
 	files = append(files, newFile("api_levels", "platform_versions.bzl", platformVersionContents(cfg)))
 
 	files = append(files, newFile("allowlists", GeneratedBuildFileName, ""))
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index 2f5dc3c..379f83b 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -159,10 +159,6 @@
 		},
 		{
 			dir:      "api_levels",
-			basename: "api_levels.bzl",
-		},
-		{
-			dir:      "api_levels",
 			basename: "platform_versions.bzl",
 		},
 		{
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 1c94741..749fce5 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -528,7 +528,7 @@
 	productVarPropNameToAttribute := map[string]*bazel.StringListAttribute{
 		"Cflags":   &ca.copts,
 		"Asflags":  &ca.asFlags,
-		"CppFlags": &ca.cppFlags,
+		"Cppflags": &ca.cppFlags,
 	}
 	for propName, attr := range productVarPropNameToAttribute {
 		if productConfigProps, exists := productVariableProps[propName]; exists {
@@ -1053,11 +1053,7 @@
 			_, staticLibs = android.RemoveFromList(versionLib, staticLibs)
 			// only add the dep if it is not in progress
 			if !versionLibAlreadyInDeps {
-				if isBinary {
-					wholeStaticLibs = append(wholeStaticLibs, versionLib)
-				} else {
-					la.implementationWholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, []string{versionLib}, props.Exclude_static_libs))
-				}
+				wholeStaticLibs = append(wholeStaticLibs, versionLib)
 			}
 		}
 	}
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index e6e5660..51f23c5 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -324,13 +324,13 @@
 						}
 					}
 				}
-				snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
+				snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, m.RelativeInstallPath(), stem)
 				ret = append(ret, copyFile(ctx, libPath, snapshotLibOut, fake))
 			} else {
 				stem = ctx.ModuleName(m)
 			}
 
-			propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json")
+			propOut = filepath.Join(snapshotArchDir, targetArch, libType, m.RelativeInstallPath(), stem+".json")
 		} else if m.Binary() {
 			// binary flags
 			prop.Symlinks = m.Symlinks()
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index 619500e..5b69a10 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -1657,3 +1657,69 @@
 		}
 	}
 }
+
+func TestSnapshotInRelativeInstallPath(t *testing.T) {
+	bp := `
+	cc_library {
+		name: "libvendor_available",
+		vendor_available: true,
+		nocrt: true,
+	}
+
+	cc_library {
+		name: "libvendor_available_var",
+		vendor_available: true,
+		stem: "libvendor_available",
+		relative_install_path: "var",
+		nocrt: true,
+	}
+`
+
+	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
+	ctx := testCcWithConfig(t, config)
+
+	// Check Vendor snapshot output.
+
+	snapshotDir := "vendor-snapshot"
+	snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
+	snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
+
+	var jsonFiles []string
+
+	for _, arch := range [][]string{
+		[]string{"arm64", "armv8-a"},
+		[]string{"arm", "armv7-a-neon"},
+	} {
+		archType := arch[0]
+		archVariant := arch[1]
+		archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
+
+		// For shared libraries, only non-VNDK vendor_available modules are captured
+		sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
+		sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+		sharedDirVar := filepath.Join(sharedDir, "var")
+		CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
+		CheckSnapshot(t, ctx, snapshotSingleton, "libvendor_available_var", "libvendor_available.so", sharedDirVar, sharedVariant)
+		jsonFiles = append(jsonFiles,
+			filepath.Join(sharedDir, "libvendor_available.so.json"),
+			filepath.Join(sharedDirVar, "libvendor_available.so.json"))
+	}
+
+	for _, jsonFile := range jsonFiles {
+		// verify all json files exist
+		if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
+			t.Errorf("%q expected but not found", jsonFile)
+		}
+	}
+
+	// fake snapshot should have all outputs in the normal snapshot.
+	fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
+	for _, output := range snapshotSingleton.AllOutputs() {
+		fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
+		if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
+			t.Errorf("%q expected but not found", fakeOutput)
+		}
+	}
+}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 53e0e55..f347b8f 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -289,9 +289,9 @@
 }
 
 // Errors out if any modules expected to be mixed_built were not, unless
-// there is a platform incompatibility.
+// the modules did not exist.
 func checkForAllowlistIntegrityError(configuration android.Config, isStagingMode bool) error {
-	modules := findModulesNotMixedBuiltForAnyVariant(configuration, isStagingMode)
+	modules := findMisconfiguredModules(configuration, isStagingMode)
 	if len(modules) == 0 {
 		return nil
 	}
@@ -299,29 +299,54 @@
 	return fmt.Errorf("Error: expected the following modules to be mixed_built: %s", modules)
 }
 
+// Returns true if the given module has all of the following true:
+//  1. Is allowlisted to be built with Bazel.
+//  2. Has a variant which is *not* built with Bazel.
+//  3. Has no variant which is built with Bazel.
+//
+// This indicates the allowlisting of this variant had no effect.
+// TODO(b/280457637): Return true for nonexistent modules.
+func isAllowlistMisconfiguredForModule(module string, mixedBuildsEnabled map[string]struct{}, mixedBuildsDisabled map[string]struct{}) bool {
+	//TODO(dacek): Why does this occur in the allowlists?
+	if module == "" {
+		return false
+	}
+	_, enabled := mixedBuildsEnabled[module]
+
+	if enabled {
+		return false
+	}
+
+	_, disabled := mixedBuildsDisabled[module]
+	return disabled
+
+}
+
 // Returns the list of modules that should have been mixed_built (per the
 // allowlists and cmdline flags) but were not.
-func findModulesNotMixedBuiltForAnyVariant(configuration android.Config, isStagingMode bool) []string {
+// Note: nonexistent modules are excluded from the list. See b/280457637
+func findMisconfiguredModules(configuration android.Config, isStagingMode bool) []string {
 	retval := []string{}
 	forceEnabledModules := configuration.BazelModulesForceEnabledByFlag()
 
 	mixedBuildsEnabled := configuration.GetMixedBuildsEnabledModules()
+	mixedBuildsDisabled := configuration.GetMixedBuildsDisabledModules()
 	for _, module := range allowlists.ProdMixedBuildsEnabledList {
-		if _, ok := mixedBuildsEnabled[module]; !ok && module != "" {
+		if isAllowlistMisconfiguredForModule(module, mixedBuildsEnabled, mixedBuildsDisabled) {
 			retval = append(retval, module)
 		}
 	}
 
 	if isStagingMode {
 		for _, module := range allowlists.StagingMixedBuildsEnabledList {
-			if _, ok := mixedBuildsEnabled[module]; !ok && module != "" {
+			if isAllowlistMisconfiguredForModule(module, mixedBuildsEnabled, mixedBuildsDisabled) {
 				retval = append(retval, module)
 			}
 		}
 	}
 
 	for module, _ := range forceEnabledModules {
-		if _, ok := mixedBuildsEnabled[module]; !ok && module != "" {
+		if isAllowlistMisconfiguredForModule(module, mixedBuildsEnabled, mixedBuildsDisabled) {
 			retval = append(retval, module)
 		}
 	}
diff --git a/java/java.go b/java/java.go
index 0da7328..d3e74fd 100644
--- a/java/java.go
+++ b/java/java.go
@@ -815,7 +815,10 @@
 	// If the min_sdk_version was set then add the canonical representation of the API level to the
 	// snapshot.
 	if j.deviceProperties.Min_sdk_version != nil {
-		canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
+		canonical, err := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String())
+		if err != nil {
+			ctx.ModuleErrorf("%s", err)
+		}
 		p.MinSdkVersion = proptools.StringPtr(canonical)
 	}
 
diff --git a/sdk/update.go b/sdk/update.go
index d98ab68..d3c59b0 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -1963,6 +1963,10 @@
 	requiredTraits android.SdkMemberTraitSet
 }
 
+func (m *memberContext) ModuleErrorf(fmt string, args ...interface{}) {
+	m.sdkMemberContext.ModuleErrorf(fmt, args...)
+}
+
 func (m *memberContext) SdkModuleContext() android.ModuleContext {
 	return m.sdkMemberContext
 }