Merge "bp2build: remove libc_nomalloc from denylist."
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 8cddbb2..63145bf 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -333,7 +333,7 @@
 	// The actual platform values here may be overridden by configuration
 	// transitions from the buildroot.
 	cmdFlags = append(cmdFlags,
-		fmt.Sprintf("--platforms=%s", "//build/bazel/platforms:android_x86_64"))
+		fmt.Sprintf("--platforms=%s", "//build/bazel/platforms:android_arm"))
 	cmdFlags = append(cmdFlags,
 		fmt.Sprintf("--extra_toolchains=%s", "//prebuilts/clang/host/linux-x86:all"))
 	// This should be parameterized on the host OS, but let's restrict to linux
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 52b1689..ce12f46 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -20,6 +20,7 @@
 	"android/soong/android"
 	"android/soong/java"
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/proptools"
 )
 
 // Contains tests for platform_bootclasspath logic from java/platform_bootclasspath.go that requires
@@ -174,6 +175,141 @@
 	})
 }
 
+// TestPlatformBootclasspath_AlwaysUsePrebuiltSdks verifies that the build does not fail when
+// AlwaysUsePrebuiltSdk() returns true. The structure of the modules in this test matches what
+// currently exists in some places in the Android build but it is not the intended structure. It is
+// in fact an invalid structure that should cause build failures. However, fixing that structure
+// will take too long so in the meantime this tests the workarounds to avoid build breakages.
+//
+// The main issues with this structure are:
+// 1. There is no prebuilt_bootclasspath_fragment referencing the "foo" java_sdk_library_import.
+// 2. There is no prebuilt_apex/apex_set which makes the dex implementation jar available to the
+//    prebuilt_bootclasspath_fragment and the "foo" java_sdk_library_import.
+//
+// Together these cause the following symptoms:
+// 1. The "foo" java_sdk_library_import does not have a dex implementation jar.
+// 2. The "foo" java_sdk_library_import does not have a myapex variant.
+//
+// TODO(b/179354495): Fix the structure in this test once the main Android build has been fixed.
+func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForTestWithPlatformBootclasspath,
+		prepareForTestWithMyapex,
+		// Configure two libraries, the first is a java_sdk_library whose prebuilt will be used because
+		// of AlwaysUsePrebuiltsSdk() but does not have an appropriate apex variant and does not provide
+		// a boot dex jar. The second is a normal library that is unaffected. The order matters because
+		// if the dependency on myapex:foo is filtered out because of either of those conditions then
+		// the dependencies resolved by the platform_bootclasspath will not match the configured list
+		// and so will fail the test.
+		java.FixtureConfigureUpdatableBootJars("myapex:foo", "myapex:bar"),
+		java.PrepareForTestWithJavaSdkLibraryFiles,
+		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+			variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
+		}),
+		java.FixtureWithPrebuiltApis(map[string][]string{
+			"current": {},
+			"30":      {"foo"},
+		}),
+	).RunTestWithBp(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			bootclasspath_fragments: [
+				"mybootclasspath-fragment",
+			],
+			updatable: false,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		java_library {
+			name: "bar",
+			srcs: ["b.java"],
+			installable: true,
+			apex_available: ["myapex"],
+			permitted_packages: ["bar"],
+		}
+
+		java_sdk_library {
+			name: "foo",
+			srcs: ["b.java"],
+			shared_library: false,
+			public: {
+				enabled: true,
+			},
+			apex_available: ["myapex"],
+			permitted_packages: ["foo"],
+		}
+
+		// A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
+		// because AlwaysUsePrebuiltSdks() is true.
+		java_sdk_library_import {
+			name: "foo",
+			prefer: false,
+			shared_library: false,
+			public: {
+				jars: ["sdk_library/public/foo-stubs.jar"],
+				stub_srcs: ["sdk_library/public/foo_stub_sources"],
+				current_api: "sdk_library/public/foo.txt",
+				removed_api: "sdk_library/public/foo-removed.txt",
+				sdk_version: "current",
+			},
+			apex_available: ["myapex"],
+		}
+
+		// This always depends on the source foo module, its dependencies are not affected by the
+		// AlwaysUsePrebuiltSdks().
+		bootclasspath_fragment {
+			name: "mybootclasspath-fragment",
+			apex_available: [
+				"myapex",
+			],
+			contents: [
+				"foo", "bar",
+			],
+		}
+
+		platform_bootclasspath {
+			name: "myplatform-bootclasspath",
+		}
+`,
+	)
+
+	java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{
+		// The configured contents of BootJars.
+		"platform:prebuilt_foo", // Note: This is the platform not myapex variant.
+		"myapex:bar",
+	})
+
+	// Make sure that the myplatform-bootclasspath has the correct dependencies.
+	CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{
+		// The following are stubs.
+		"platform:prebuilt_sdk_public_current_android",
+		"platform:prebuilt_sdk_system_current_android",
+		"platform:prebuilt_sdk_test_current_android",
+
+		// Not a prebuilt as no prebuilt existed when it was added.
+		"platform:legacy.core.platform.api.stubs",
+
+		// Needed for generating the boot image.
+		`platform:dex2oatd`,
+
+		// The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
+		// modules when available as it does not know which one will be preferred.
+		//
+		// The source module has an APEX variant but the prebuilt does not.
+		"myapex:foo",
+		"platform:prebuilt_foo",
+
+		// Only a source module exists.
+		"myapex:bar",
+	})
+}
+
 // CheckModuleDependencies checks the dependencies of the selected module against the expected list.
 //
 // The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 63a6c2e..71660a8 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -324,11 +324,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
-		if Errored(t, "", errs) {
+		if errored(t, "", errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, "", errs) {
+		if errored(t, "", errs) {
 			continue
 		}
 
@@ -925,11 +925,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
@@ -957,17 +957,6 @@
 	}
 }
 
-func Errored(t *testing.T, desc string, errs []error) bool {
-	t.Helper()
-	if len(errs) > 0 {
-		for _, err := range errs {
-			t.Errorf("%s: %s", desc, err)
-		}
-		return true
-	}
-	return false
-}
-
 type bp2buildMutator = func(android.TopDownMutatorContext)
 
 func TestBp2BuildInlinesDefaults(t *testing.T) {
@@ -1483,11 +1472,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
@@ -1606,11 +1595,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 32b12e4..204c519 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -22,8 +22,6 @@
 	"testing"
 )
 
-var buildDir string
-
 func setUp() {
 	var err error
 	buildDir, err = ioutil.TempDir("", "bazel_queryview_test")
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index da5444c..a1ffabc 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -617,11 +617,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 1202da6..a3965ed 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -385,11 +385,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index bb12462..4fcf5e4 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1132,11 +1132,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index ea8b9f1..ebc9c94 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -228,11 +228,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
@@ -411,11 +411,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 2054e06..ed509bf 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -128,11 +128,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index 37f542e..575bf58 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -101,11 +101,11 @@
 		ctx.RegisterForBazelConversion()
 
 		_, errs := ctx.ParseFileList(dir, toParse)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 		_, errs = ctx.ResolveDependencies(config)
-		if Errored(t, testCase.description, errs) {
+		if errored(t, testCase.description, errs) {
 			continue
 		}
 
diff --git a/bp2build/testing.go b/bp2build/testing.go
index b925682..e575bc6 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -1,6 +1,8 @@
 package bp2build
 
 import (
+	"testing"
+
 	"android/soong/android"
 	"android/soong/bazel"
 )
@@ -10,6 +12,8 @@
 	bp2buildConfig = android.Bp2BuildConfig{
 		android.BP2BUILD_TOPLEVEL: android.Bp2BuildDefaultTrueRecursively,
 	}
+
+	buildDir string
 )
 
 type nestedProps struct {
@@ -39,6 +43,17 @@
 	props customProps
 }
 
+func errored(t *testing.T, desc string, errs []error) bool {
+	t.Helper()
+	if len(errs) > 0 {
+		for _, err := range errs {
+			t.Errorf("%s: %s", desc, err)
+		}
+		return true
+	}
+	return false
+}
+
 // OutputFiles is needed because some instances of this module use dist with a
 // tag property which requires the module implements OutputFileProducer.
 func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
diff --git a/cc/linker.go b/cc/linker.go
index 196806d..5bd21ed 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -393,7 +393,7 @@
 	if ctx.minSdkVersion() == "current" {
 		return true
 	}
-	parsedSdkVersion, err := android.ApiLevelFromUser(ctx, ctx.minSdkVersion())
+	parsedSdkVersion, err := nativeApiLevelFromUser(ctx, ctx.minSdkVersion())
 	if err != nil {
 		ctx.PropertyErrorf("min_sdk_version",
 			"Invalid min_sdk_version value (must be int or current): %q",
@@ -424,7 +424,7 @@
 			// ANDROID_RELR relocations were supported at API level >= 28.
 			// Relocation packer was supported at API level >= 23.
 			// Do the best we can...
-			if !ctx.useSdk() || CheckSdkVersionAtLeast(ctx, android.FirstShtRelrVersion) {
+			if (!ctx.useSdk() && ctx.minSdkVersion() == "") || CheckSdkVersionAtLeast(ctx, android.FirstShtRelrVersion) {
 				flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android+relr")
 			} else if CheckSdkVersionAtLeast(ctx, android.FirstAndroidRelrVersion) {
 				flags.Global.LdFlags = append(flags.Global.LdFlags,
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index 02833ab..634959a 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -29,7 +29,7 @@
 
 func registerBootclasspathBuildComponents(ctx android.RegistrationContext) {
 	ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator)
+		ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator).Parallel()
 	})
 }
 
@@ -95,6 +95,15 @@
 	if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
 		ctx.AddVariationDependencies(variations, tag, prebuiltName)
 		addedDep = true
+	} else if ctx.Config().AlwaysUsePrebuiltSdks() && len(variations) > 0 {
+		// TODO(b/179354495): Remove this code path once the Android build has been fully migrated to
+		//  use bootclasspath_fragment properly.
+		// Some prebuilt java_sdk_library modules do not yet have an APEX variations so try and add a
+		// dependency on the non-APEX variant.
+		if ctx.OtherModuleDependencyVariantExists(nil, prebuiltName) {
+			ctx.AddVariationDependencies(nil, tag, prebuiltName)
+			addedDep = true
+		}
 	}
 
 	// If no appropriate variant existing for this, so no dependency could be added, then it is an
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index e9f7c44..e1a3650 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -766,7 +766,7 @@
 			if len(pp) > 0 {
 				updatablePackages = append(updatablePackages, pp...)
 			} else {
-				ctx.ModuleErrorf("Missing permitted_packages")
+				ctx.OtherModuleErrorf(module, "Missing permitted_packages")
 			}
 		}
 	}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 2dceb65..f5afe5d 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -15,6 +15,7 @@
 package java
 
 import (
+	"fmt"
 	"strings"
 
 	"android/soong/android"
@@ -560,7 +561,25 @@
 	for _, module := range contents {
 		bootDexJar := module.bootDexJar()
 		if bootDexJar == nil {
-			ctx.ModuleErrorf("module %s does not provide a dex jar", module)
+			if ctx.Config().AlwaysUsePrebuiltSdks() {
+				// TODO(b/179354495): Remove this work around when it is unnecessary.
+				// Prebuilt modules like framework-wifi do not yet provide dex implementation jars. So,
+				// create a fake one that will cause a build error only if it is used.
+				fake := android.PathForModuleOut(ctx, "fake/boot-dex/%s.jar", module.Name())
+
+				// Create an error rule that pretends to create the output file but will actually fail if it
+				// is run.
+				ctx.Build(pctx, android.BuildParams{
+					Rule:   android.ErrorRule,
+					Output: fake,
+					Args: map[string]string{
+						"error": fmt.Sprintf("missing dependencies: boot dex jar for %s", module),
+					},
+				})
+				bootDexJars = append(bootDexJars, fake)
+			} else {
+				ctx.ModuleErrorf("module %s does not provide a dex jar", module)
+			}
 		} else {
 			bootDexJars = append(bootDexJars, bootDexJar)
 		}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index c8fafed..6ebeb6b 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -242,8 +242,15 @@
 		} else {
 			name := ctx.OtherModuleName(m)
 			if apexInfo.IsForPlatform() {
-				// error: this jar is part of the platform
-				ctx.ModuleErrorf("module %q from platform is not allowed in the updatable boot jars list", name)
+				// If AlwaysUsePrebuiltSdks() returns true then it is possible that the updatable list will
+				// include platform variants of a prebuilt module due to workarounds elsewhere. In that case
+				// do not treat this as an error.
+				// TODO(b/179354495): Always treat this as an error when migration to bootclasspath_fragment
+				//  modules is complete.
+				if !ctx.Config().AlwaysUsePrebuiltSdks() {
+					// error: this jar is part of the platform
+					ctx.ModuleErrorf("module %q from platform is not allowed in the updatable boot jars list", name)
+				}
 			} else {
 				// TODO(b/177892522): Treat this as an error.
 				// Cannot do that at the moment because framework-wifi and framework-tethering are in the