Merge "Migrate overlapping config var defs in all bp file"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 5fc5a62..af24bea 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -689,11 +689,18 @@
 
 		//kotlin srcs in android_binary
 		"MusicKotlin",
+
+		// checked in current.txt for merged_txts
+		"non-updatable-current.txt",
+		"non-updatable-system-current.txt",
+		"non-updatable-module-lib-current.txt",
+		"non-updatable-system-server-current.txt",
 	}
 
 	Bp2buildModuleTypeAlwaysConvertList = []string{
 		"aidl_interface_headers",
 		"bpf",
+		"combined_apis",
 		"license",
 		"linker_config",
 		"java_import",
diff --git a/android/arch_list.go b/android/arch_list.go
index 578904c..97bbc63 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -71,6 +71,7 @@
 		"cortex-a8",
 		"cortex-a9",
 		"cortex-a15",
+		"cortex-a32",
 		"cortex-a53",
 		"cortex-a53.a57",
 		"cortex-a55",
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c94bbbb..707cc63 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -9788,30 +9788,85 @@
 		apex {
 			name: "myapex",
 			key: "myapex.key",
-			native_shared_libs: ["libfoo"],
+			native_shared_libs: ["libbaz"],
+			binaries: ["binfoo"],
 			min_sdk_version: "29",
 		}
 		apex_key {
 			name: "myapex.key",
 		}
-		cc_library {
-			name: "libfoo",
-			shared_libs: ["libc"],
+		cc_binary {
+			name: "binfoo",
+			shared_libs: ["libbar", "libbaz", "libqux",],
 			apex_available: ["myapex"],
 			min_sdk_version: "29",
+			recovery_available: false,
+		}
+		cc_library {
+			name: "libbar",
+			srcs: ["libbar.cc"],
+			stubs: {
+				symbol_file: "libbar.map.txt",
+				versions: [
+					"29",
+				],
+			},
+		}
+		cc_library {
+			name: "libbaz",
+			srcs: ["libbaz.cc"],
+			apex_available: ["myapex"],
+			min_sdk_version: "29",
+			stubs: {
+				symbol_file: "libbaz.map.txt",
+				versions: [
+					"29",
+				],
+			},
 		}
 		cc_api_library {
-			name: "libc",
-			src: "libc.so",
+			name: "libbar",
+			src: "libbar_stub.so",
 			min_sdk_version: "29",
-			recovery_available: true,
+			variants: ["apex.29"],
+		}
+		cc_api_variant {
+			name: "libbar",
+			variant: "apex",
+			version: "29",
+			src: "libbar_apex_29.so",
+		}
+		cc_api_library {
+			name: "libbaz",
+			src: "libbaz_stub.so",
+			min_sdk_version: "29",
+			variants: ["apex.29"],
+		}
+		cc_api_variant {
+			name: "libbaz",
+			variant: "apex",
+			version: "29",
+			src: "libbaz_apex_29.so",
+		}
+		cc_api_library {
+			name: "libqux",
+			src: "libqux_stub.so",
+			min_sdk_version: "29",
+			variants: ["apex.29"],
+		}
+		cc_api_variant {
+			name: "libqux",
+			variant: "apex",
+			version: "29",
+			src: "libqux_apex_29.so",
 		}
 		api_imports {
 			name: "api_imports",
-			shared_libs: [
-				"libc",
+			apex_shared_libs: [
+				"libbar",
+				"libbaz",
+				"libqux",
 			],
-			header_libs: [],
 		}
 		`
 	result := testApex(t, bp)
@@ -9827,17 +9882,107 @@
 		return found
 	}
 
-	libfooApexVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex29").Module()
-	libcApexVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared_apex29").Module()
+	// Library defines stubs and cc_api_library should be used with cc_api_library
+	binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Module()
+	libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+	libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
 
-	android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(libfooApexVariant, libcApexVariant))
+	android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
+	android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
 
-	// libfoo core variant should be buildable in the same inner tree since
-	// certain mcombo files might build system and apexes in the same inner tree
-	// libfoo core variant should link against source libc
-	libfooCoreVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
-	libcCoreVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared").Module()
-	android.AssertBoolEquals(t, "core variant should link against source libc", true, hasDep(libfooCoreVariant, libcCoreVariant))
+	binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Rule("ld").Args["libFlags"]
+	android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
+	android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
+	android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
+
+	// Library defined in the same APEX should be linked with original definition instead of cc_api_library
+	libbazApexVariant := result.ModuleForTests("libbaz", "android_arm64_armv8-a_shared_apex29").Module()
+	libbazApiImportCoreVariant := result.ModuleForTests("libbaz.apiimport", "android_arm64_armv8-a_shared").Module()
+	android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even from same APEX", true, hasDep(binfooApexVariant, libbazApiImportCoreVariant))
+	android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbazApexVariant))
+
+	android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbaz.so")
+	android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbaz.apiimport.so")
+	android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbaz.apex.29.apiimport.so")
+
+	// cc_api_library defined without original library should be linked with cc_api_library
+	libquxApiImportApexVariant := result.ModuleForTests("libqux.apiimport", "android_arm64_armv8-a_shared").Module()
+	android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even original library definition does not exist", true, hasDep(binfooApexVariant, libquxApiImportApexVariant))
+	android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libqux.apex.29.apiimport.so")
+}
+
+func TestPlatformBinaryBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
+	bp := `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["libbar"],
+			min_sdk_version: "29",
+		}
+		apex_key {
+			name: "myapex.key",
+		}
+		cc_binary {
+			name: "binfoo",
+			shared_libs: ["libbar"],
+			recovery_available: false,
+		}
+		cc_library {
+			name: "libbar",
+			srcs: ["libbar.cc"],
+			apex_available: ["myapex"],
+			min_sdk_version: "29",
+			stubs: {
+				symbol_file: "libbar.map.txt",
+				versions: [
+					"29",
+				],
+			},
+		}
+		cc_api_library {
+			name: "libbar",
+			src: "libbar_stub.so",
+			variants: ["apex.29"],
+		}
+		cc_api_variant {
+			name: "libbar",
+			variant: "apex",
+			version: "29",
+			src: "libbar_apex_29.so",
+		}
+		api_imports {
+			name: "api_imports",
+			apex_shared_libs: [
+				"libbar",
+			],
+		}
+		`
+
+	result := testApex(t, bp)
+
+	hasDep := func(m android.Module, wantDep android.Module) bool {
+		t.Helper()
+		var found bool
+		result.VisitDirectDeps(m, func(dep blueprint.Module) {
+			if dep == wantDep {
+				found = true
+			}
+		})
+		return found
+	}
+
+	// Library defines stubs and cc_api_library should be used with cc_api_library
+	binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Module()
+	libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+	libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+
+	android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
+	android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
+
+	binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
+	android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
+	android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
+	android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
 }
 
 func TestTrimmedApex(t *testing.T) {
diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go
index 2fe158e..c5a6dfd 100644
--- a/bp2build/cc_prebuilt_library_conversion_test.go
+++ b/bp2build/cc_prebuilt_library_conversion_test.go
@@ -39,6 +39,10 @@
 				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static_alwayslink", AttrNameToString{
+					"static_library": `"libf.so"`,
+					"alwayslink":     "True",
+				}),
 				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
 				}),
@@ -71,8 +75,14 @@
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
         "//conditions:default": None,
-    })`,
-				}),
+    })`}),
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static_alwayslink", AttrNameToString{
+					"alwayslink": "True",
+					"static_library": `select({
+        "//build/bazel/platforms/arch:arm": "libg.so",
+        "//build/bazel/platforms/arch:arm64": "libf.so",
+        "//conditions:default": None,
+    })`}),
 				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `select({
         "//build/bazel/platforms/arch:arm": "libg.so",
@@ -109,6 +119,12 @@
 					"export_includes":        `["testdir/1/"]`,
 					"export_system_includes": `["testdir/2/"]`,
 				}),
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static_alwayslink", AttrNameToString{
+					"static_library":         `"libf.so"`,
+					"export_includes":        `["testdir/1/"]`,
+					"export_system_includes": `["testdir/2/"]`,
+					"alwayslink":             "True",
+				}),
 				// TODO(b/229374533): When fixed, update this test
 				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libf.so"`,
@@ -188,6 +204,10 @@
 				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static_alwayslink", AttrNameToString{
+					"static_library": `"libf.so"`,
+					"alwayslink":     "True",
+				}),
 				MakeBazelTarget("cc_prebuilt_library_shared", "libtest", AttrNameToString{
 					"shared_library": `"libg.so"`,
 				}),
@@ -245,6 +265,10 @@
 //				makeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
 //					"static_library": `"libf.so"`,
 //				}),
+//				makeBazelTarget("cc_prebuilt_library_static", "libtest_bp2build_cc_library_static_always", attrNameToString{
+//					"static_library": `"libf.so"`,
+//					"alwayslink": "True",
+//				}),
 //			},
 //		})
 //}
diff --git a/bp2build/cc_prebuilt_library_static_test.go b/bp2build/cc_prebuilt_library_static_test.go
index 6116b00..17da813 100644
--- a/bp2build/cc_prebuilt_library_static_test.go
+++ b/bp2build/cc_prebuilt_library_static_test.go
@@ -39,6 +39,10 @@
 				MakeBazelTarget("cc_prebuilt_library_static", "libtest", AttrNameToString{
 					"static_library": `"libf.so"`,
 				}),
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_alwayslink", AttrNameToString{
+					"static_library": `"libf.so"`,
+					"alwayslink":     "True",
+				}),
 			},
 		})
 }
@@ -68,8 +72,14 @@
         "//build/bazel/platforms/arch:arm": "libg.so",
         "//build/bazel/platforms/arch:arm64": "libf.so",
         "//conditions:default": None,
-    })`,
-				}),
+    })`}),
+				MakeBazelTarget("cc_prebuilt_library_static", "libtest_alwayslink", AttrNameToString{
+					"alwayslink": "True",
+					"static_library": `select({
+        "//build/bazel/platforms/arch:arm": "libg.so",
+        "//build/bazel/platforms/arch:arm64": "libf.so",
+        "//conditions:default": None,
+    })`}),
 			},
 		})
 }
diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go
index 46105c7..6f17e34 100644
--- a/bp2build/java_binary_host_conversion_test.go
+++ b/bp2build/java_binary_host_conversion_test.go
@@ -221,6 +221,11 @@
         "a.java",
         "b.kt",
     ]`,
+				"resources": `[
+        "res/a.res",
+        "res/dir1/b.res",
+    ]`,
+				"resource_strip_prefix": `"res"`,
 				"target_compatible_with": `select({
         "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
         "//conditions:default": [],
@@ -229,11 +234,6 @@
 			MakeBazelTarget("java_binary", "java-binary-host", AttrNameToString{
 				"main_class":   `"com.android.test.MainClass"`,
 				"runtime_deps": `[":java-binary-host_kt"]`,
-				"resources": `[
-        "res/a.res",
-        "res/dir1/b.res",
-    ]`,
-				"resource_strip_prefix": `"res"`,
 				"target_compatible_with": `select({
         "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
         "//conditions:default": [],
diff --git a/cc/cc.go b/cc/cc.go
index c07d836..0e88c56 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2416,6 +2416,27 @@
 	return nonVariantLibs, variantLibs
 }
 
+func (c *Module) shouldUseApiSurface() bool {
+	if c.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
+		if GetImageVariantType(c) == vendorImageVariant || GetImageVariantType(c) == productImageVariant {
+			// LLNDK Variant
+			return true
+		}
+
+		if c.Properties.IsSdkVariant {
+			// NDK Variant
+			return true
+		}
+
+		if c.isImportedApiLibrary() {
+			// API Library should depend on API headers
+			return true
+		}
+	}
+
+	return false
+}
+
 func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
 	if !c.Enabled() {
 		return
@@ -2435,7 +2456,7 @@
 	apiNdkLibs := []string{}
 	apiLateNdkLibs := []string{}
 
-	if ctx.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
+	if c.shouldUseApiSurface() {
 		deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config())
 		deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
 		deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
@@ -2466,7 +2487,7 @@
 		}
 
 		// Check header lib replacement from API surface first, and then check again with VSDK
-		if ctx.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
+		if c.shouldUseApiSurface() {
 			lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs)
 		}
 		lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
@@ -2550,12 +2571,22 @@
 		}
 
 		name, version := StubsLibNameAndVersion(lib)
+		if apiLibraryName, ok := apiImportInfo.SharedLibs[name]; ok && !ctx.OtherModuleExists(name) {
+			name = apiLibraryName
+		}
 		sharedLibNames = append(sharedLibNames, name)
 
 		variations := []blueprint.Variation{
 			{Mutator: "link", Variation: "shared"},
 		}
-		AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
+
+		if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
+			AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
+		}
+
+		if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok {
+			AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, apiLibraryName, version, false)
+		}
 	}
 
 	for _, lib := range deps.LateStaticLibs {
@@ -2898,10 +2929,58 @@
 	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
 	c.apexSdkVersion = findApexSdkVersion(ctx, apexInfo)
 
+	skipModuleList := map[string]bool{}
+
+	var apiImportInfo multitree.ApiImportInfo
+	hasApiImportInfo := false
+
+	ctx.VisitDirectDeps(func(dep android.Module) {
+		if dep.Name() == "api_imports" {
+			apiImportInfo = ctx.OtherModuleProvider(dep, multitree.ApiImportsProvider).(multitree.ApiImportInfo)
+			hasApiImportInfo = true
+		}
+	})
+
+	if hasApiImportInfo {
+		targetStubModuleList := map[string]string{}
+		targetOrigModuleList := map[string]string{}
+
+		// Search for dependency which both original module and API imported library with APEX stub exists
+		ctx.VisitDirectDeps(func(dep android.Module) {
+			depName := ctx.OtherModuleName(dep)
+			if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok {
+				targetStubModuleList[apiLibrary] = depName
+			}
+		})
+		ctx.VisitDirectDeps(func(dep android.Module) {
+			depName := ctx.OtherModuleName(dep)
+			if origLibrary, ok := targetStubModuleList[depName]; ok {
+				targetOrigModuleList[origLibrary] = depName
+			}
+		})
+
+		// Decide which library should be used between original and API imported library
+		ctx.VisitDirectDeps(func(dep android.Module) {
+			depName := ctx.OtherModuleName(dep)
+			if apiLibrary, ok := targetOrigModuleList[depName]; ok {
+				if shouldUseStubForApex(ctx, dep) {
+					skipModuleList[depName] = true
+				} else {
+					skipModuleList[apiLibrary] = true
+				}
+			}
+		})
+	}
+
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		depName := ctx.OtherModuleName(dep)
 		depTag := ctx.OtherModuleDependencyTag(dep)
 
+		if _, ok := skipModuleList[depName]; ok {
+			// skip this module because original module or API imported module matching with this should be used instead.
+			return
+		}
+
 		if depTag == android.DarwinUniversalVariantTag {
 			depPaths.DarwinSecondArchOutput = dep.(*Module).OutputFile()
 			return
@@ -3237,21 +3316,8 @@
 	return depPaths
 }
 
-// ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant
-// of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right
-// dependency. The stub variant is selected when the dependency crosses a boundary where each side
-// has different level of updatability. For example, if a library foo in an APEX depends on a
-// library bar which provides stable interface and exists in the platform, foo uses the stub variant
-// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
-// same APEX as foo, the non-stub variant of bar is used.
-func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
+func shouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool {
 	depName := ctx.OtherModuleName(dep)
-	depTag := ctx.OtherModuleDependencyTag(dep)
-	libDepTag, ok := depTag.(libraryDependencyTag)
-	if !ok || !libDepTag.shared() {
-		panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
-	}
-
 	thisModule, ok := ctx.Module().(android.ApexModule)
 	if !ok {
 		panic(fmt.Errorf("Not an APEX module: %q", ctx.ModuleName()))
@@ -3266,62 +3332,93 @@
 		bootstrap = linkable.Bootstrap()
 	}
 
+	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+
+	useStubs := false
+
+	if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK
+		if !apexInfo.IsForPlatform() {
+			// For platform libraries, use current version of LLNDK
+			// If this is for use_vendor apex we will apply the same rules
+			// of apex sdk enforcement below to choose right version.
+			useStubs = true
+		}
+	} else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis {
+		// If not building for APEX or the containing APEX allows the use of
+		// platform APIs, use stubs only when it is from an APEX (and not from
+		// platform) However, for host, ramdisk, vendor_ramdisk, recovery or
+		// bootstrap modules, always link to non-stub variant
+		isNotInPlatform := dep.(android.ApexModule).NotInPlatform()
+
+		isApexImportedApiLibrary := false
+
+		if cc, ok := dep.(*Module); ok {
+			if apiLibrary, ok := cc.linker.(*apiLibraryDecorator); ok {
+				if apiLibrary.hasApexStubs() {
+					isApexImportedApiLibrary = true
+				}
+			}
+		}
+
+		useStubs = (isNotInPlatform || isApexImportedApiLibrary) && !bootstrap
+
+		if useStubs {
+			// Another exception: if this module is a test for an APEX, then
+			// it is linked with the non-stub variant of a module in the APEX
+			// as if this is part of the APEX.
+			testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
+			for _, apexContents := range testFor.ApexContents {
+				if apexContents.DirectlyInApex(depName) {
+					useStubs = false
+					break
+				}
+			}
+		}
+		if useStubs {
+			// Yet another exception: If this module and the dependency are
+			// available to the same APEXes then skip stubs between their
+			// platform variants. This complements the test_for case above,
+			// which avoids the stubs on a direct APEX library dependency, by
+			// avoiding stubs for indirect test dependencies as well.
+			//
+			// TODO(b/183882457): This doesn't work if the two libraries have
+			// only partially overlapping apex_available. For that test_for
+			// modules would need to be split into APEX variants and resolved
+			// separately for each APEX they have access to.
+			if !isApexImportedApiLibrary && android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
+				useStubs = false
+			}
+		}
+	} else {
+		// If building for APEX, use stubs when the parent is in any APEX that
+		// the child is not in.
+		useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
+	}
+
+	return useStubs
+}
+
+// ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant
+// of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right
+// dependency. The stub variant is selected when the dependency crosses a boundary where each side
+// has different level of updatability. For example, if a library foo in an APEX depends on a
+// library bar which provides stable interface and exists in the platform, foo uses the stub variant
+// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
+// same APEX as foo, the non-stub variant of bar is used.
+func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
+	depTag := ctx.OtherModuleDependencyTag(dep)
+	libDepTag, ok := depTag.(libraryDependencyTag)
+	if !ok || !libDepTag.shared() {
+		panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
+	}
+
 	sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo)
 	depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
 	sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryStubsProvider).(SharedLibraryStubsInfo)
-	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
 
 	if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 {
-		useStubs := false
-
-		if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK
-			if !apexInfo.IsForPlatform() {
-				// For platform libraries, use current version of LLNDK
-				// If this is for use_vendor apex we will apply the same rules
-				// of apex sdk enforcement below to choose right version.
-				useStubs = true
-			}
-		} else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis {
-			// If not building for APEX or the containing APEX allows the use of
-			// platform APIs, use stubs only when it is from an APEX (and not from
-			// platform) However, for host, ramdisk, vendor_ramdisk, recovery or
-			// bootstrap modules, always link to non-stub variant
-			useStubs = dep.(android.ApexModule).NotInPlatform() && !bootstrap
-			if useStubs {
-				// Another exception: if this module is a test for an APEX, then
-				// it is linked with the non-stub variant of a module in the APEX
-				// as if this is part of the APEX.
-				testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
-				for _, apexContents := range testFor.ApexContents {
-					if apexContents.DirectlyInApex(depName) {
-						useStubs = false
-						break
-					}
-				}
-			}
-			if useStubs {
-				// Yet another exception: If this module and the dependency are
-				// available to the same APEXes then skip stubs between their
-				// platform variants. This complements the test_for case above,
-				// which avoids the stubs on a direct APEX library dependency, by
-				// avoiding stubs for indirect test dependencies as well.
-				//
-				// TODO(b/183882457): This doesn't work if the two libraries have
-				// only partially overlapping apex_available. For that test_for
-				// modules would need to be split into APEX variants and resolved
-				// separately for each APEX they have access to.
-				if android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
-					useStubs = false
-				}
-			}
-		} else {
-			// If building for APEX, use stubs when the parent is in any APEX that
-			// the child is not in.
-			useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
-		}
-
 		// when to use (unspecified) stubs, use the latest one.
-		if useStubs {
+		if shouldUseStubForApex(ctx, dep) {
 			stubs := sharedLibraryStubsInfo.SharedStubLibraries
 			toUse := stubs[len(stubs)-1]
 			sharedLibraryInfo = toUse.SharedLibraryInfo
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 981d1ea..0704550 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -97,6 +97,15 @@
 			// better solution comes around. See Bug 27340895
 			"-D__ARM_FEATURE_LPAE=1",
 		},
+		"cortex-a32": []string{
+			"-mcpu=cortex-a32",
+			"-mfpu=neon-vfpv4",
+			// Fake an ARM compiler flag as these processors support LPAE which clang
+			// don't advertise.
+			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
+			// better solution comes around. See Bug 27340895
+			"-D__ARM_FEATURE_LPAE=1",
+		},
 		"cortex-a53": []string{
 			"-mcpu=cortex-a53",
 			"-mfpu=neon-fp-armv8",
@@ -204,6 +213,7 @@
 	exportedVars.ExportStringListStaticVariable("ArmCortexA7Cflags", armCpuVariantCflags["cortex-a7"])
 	exportedVars.ExportStringListStaticVariable("ArmCortexA8Cflags", armCpuVariantCflags["cortex-a8"])
 	exportedVars.ExportStringListStaticVariable("ArmCortexA15Cflags", armCpuVariantCflags["cortex-a15"])
+	exportedVars.ExportStringListStaticVariable("ArmCortexA32Cflags", armCpuVariantCflags["cortex-a32"])
 	exportedVars.ExportStringListStaticVariable("ArmCortexA53Cflags", armCpuVariantCflags["cortex-a53"])
 	exportedVars.ExportStringListStaticVariable("ArmCortexA55Cflags", armCpuVariantCflags["cortex-a55"])
 	exportedVars.ExportStringListStaticVariable("ArmKraitCflags", armCpuVariantCflags["krait"])
@@ -224,6 +234,7 @@
 		"cortex-a8":      "${config.ArmCortexA8Cflags}",
 		"cortex-a9":      "${config.ArmGenericCflags}",
 		"cortex-a15":     "${config.ArmCortexA15Cflags}",
+		"cortex-a32":     "${config.ArmCortexA32Cflags}",
 		"cortex-a53":     "${config.ArmCortexA53Cflags}",
 		"cortex-a53.a57": "${config.ArmCortexA53Cflags}",
 		"cortex-a55":     "${config.ArmCortexA55Cflags}",
diff --git a/cc/library_stub.go b/cc/library_stub.go
index 08a5eb6..18d3f21 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -23,7 +23,8 @@
 )
 
 var (
-	ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
+	ndkVariantRegex  = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
+	stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)")
 )
 
 func init() {
@@ -60,6 +61,12 @@
 			variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
 			ctx.AddDependency(m, nil, variantName)
 		}
+	} else if m.IsStubs() {
+		targetVariant := "apex." + m.StubsVersion()
+		if inList(targetVariant, apiLibrary.properties.Variants) {
+			variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
+			ctx.AddDependency(m, nil, variantName)
+		}
 	}
 }
 
@@ -153,15 +160,15 @@
 		in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
 	}
 
-	// LLNDK variant
-	if m.UseVndk() && d.hasLLNDKStubs() {
-		apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
+	libName := m.BaseModuleName() + multitree.GetApiImportSuffix()
 
+	load_cc_variant := func(apiVariantModule string) {
 		var mod android.Module
 
 		ctx.VisitDirectDeps(func(depMod android.Module) {
 			if depMod.Name() == apiVariantModule {
 				mod = depMod
+				libName = apiVariantModule
 			}
 		})
 
@@ -184,37 +191,17 @@
 				}
 			}
 		}
+	}
+
+	if m.UseVndk() && d.hasLLNDKStubs() {
+		// LLNDK variant
+		load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", ""))
 	} else if m.IsSdkVariant() {
 		// NDK Variant
-		apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion())
-
-		var mod android.Module
-
-		ctx.VisitDirectDeps(func(depMod android.Module) {
-			if depMod.Name() == apiVariantModule {
-				mod = depMod
-			}
-		})
-
-		if mod != nil {
-			variantMod, ok := mod.(*CcApiVariant)
-			if ok {
-				in = variantMod.Src()
-
-				// Copy NDK properties to cc_api_library module
-				d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append(
-					d.libraryDecorator.flagExporter.Properties.Export_include_dirs,
-					variantMod.exportProperties.Export_include_dirs...)
-
-				// Export headers as system include dirs if specified. Mostly for libc
-				if Bool(variantMod.exportProperties.Export_headers_as_system) {
-					d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append(
-						d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs,
-						d.libraryDecorator.flagExporter.Properties.Export_include_dirs...)
-					d.libraryDecorator.flagExporter.Properties.Export_include_dirs = nil
-				}
-			}
-		}
+		load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion()))
+	} else if m.IsStubs() {
+		// APEX Variant
+		load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion()))
 	}
 
 	// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
@@ -237,20 +224,58 @@
 	d.libraryDecorator.flagExporter.setProvider(ctx)
 
 	d.unstrippedOutputFile = in
-	libName := d.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
+	libName += flags.Toolchain.ShlibSuffix()
 
 	tocFile := android.PathForModuleOut(ctx, libName+".toc")
 	d.tocFile = android.OptionalPathForPath(tocFile)
 	TransformSharedObjectToToc(ctx, in, tocFile)
 
+	outputFile := android.PathForModuleOut(ctx, libName)
+
+	// TODO(b/270485584) This copies with a new name, just to avoid conflict with prebuilts.
+	// We can just use original input if there is any way to avoid name conflict without copy.
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        android.Cp,
+		Description: "API surface imported library",
+		Input:       in,
+		Output:      outputFile,
+		Args: map[string]string{
+			"cpFlags": "-L",
+		},
+	})
+
 	ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
-		SharedLibrary: in,
+		SharedLibrary: outputFile,
 		Target:        ctx.Target(),
 
 		TableOfContents: d.tocFile,
 	})
 
-	return in
+	d.shareStubs(ctx)
+
+	return outputFile
+}
+
+// Share additional information about stub libraries with provider
+func (d *apiLibraryDecorator) shareStubs(ctx ModuleContext) {
+	stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
+	if len(stubs) > 0 {
+		var stubsInfo []SharedStubLibrary
+		for _, stub := range stubs {
+			stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo)
+			flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo)
+			stubsInfo = append(stubsInfo, SharedStubLibrary{
+				Version:           moduleLibraryInterface(stub).stubsVersion(),
+				SharedLibraryInfo: stubInfo,
+				FlagExporterInfo:  flagInfo,
+			})
+		}
+		ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{
+			SharedStubLibraries: stubsInfo,
+
+			IsLLNDK: ctx.IsLlndk(),
+		})
+	}
 }
 
 func (d *apiLibraryDecorator) availableFor(what string) bool {
@@ -258,6 +283,19 @@
 	return true
 }
 
+func (d *apiLibraryDecorator) hasApexStubs() bool {
+	for _, variant := range d.properties.Variants {
+		if strings.HasPrefix(variant, "apex") {
+			return true
+		}
+	}
+	return false
+}
+
+func (d *apiLibraryDecorator) hasStubsVariants() bool {
+	return d.hasApexStubs()
+}
+
 func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
 	m, ok := ctx.Module().(*Module)
 
@@ -265,14 +303,8 @@
 		return nil
 	}
 
-	if d.hasLLNDKStubs() && m.UseVndk() {
-		// LLNDK libraries only need a single stubs variant.
-		return []string{android.FutureApiLevel.String()}
-	}
-
 	// TODO(b/244244438) Create more version information for NDK and APEX variations
 	// NDK variants
-
 	if m.IsSdkVariant() {
 		// TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant.
 		if d.hasNDKStubs() {
@@ -280,6 +312,17 @@
 		}
 	}
 
+	if d.hasLLNDKStubs() && m.UseVndk() {
+		// LLNDK libraries only need a single stubs variant.
+		return []string{android.FutureApiLevel.String()}
+	}
+
+	stubsVersions := d.getStubVersions()
+
+	if len(stubsVersions) != 0 {
+		return stubsVersions
+	}
+
 	if m.MinSdkVersion() == "" {
 		return nil
 	}
@@ -319,6 +362,18 @@
 	return ndkVersions
 }
 
+func (d *apiLibraryDecorator) getStubVersions() []string {
+	stubVersions := []string{}
+
+	for _, variant := range d.properties.Variants {
+		if match := stubVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
+			stubVersions = append(stubVersions, match[1])
+		}
+	}
+
+	return stubVersions
+}
+
 // 'cc_api_headers' is similar with 'cc_api_library', but which replaces
 // header libraries. The module will replace any dependencies to existing
 // original header libraries.
@@ -433,7 +488,7 @@
 // Implement ImageInterface to generate image variants
 func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
 func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
-	return String(v.properties.Variant) == "ndk"
+	return inList(String(v.properties.Variant), []string{"ndk", "apex"})
 }
 func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool       { return false }
 func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
diff --git a/cc/library_stub_test.go b/cc/library_stub_test.go
index 868447a..528577a 100644
--- a/cc/library_stub_test.go
+++ b/cc/library_stub_test.go
@@ -41,6 +41,7 @@
 		cc_library {
 			name: "libfoo",
 			shared_libs: ["libbar"],
+			vendor_available: true,
 		}
 
 		cc_library {
@@ -49,6 +50,7 @@
 
 		cc_api_library {
 			name: "libbar",
+			vendor_available: true,
 			src: "libbar.so",
 		}
 
@@ -57,7 +59,6 @@
 			shared_libs: [
 				"libbar",
 			],
-			header_libs: [],
 		}
 	`
 
@@ -67,8 +68,14 @@
 	libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
 	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
 
-	android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbar))
-	android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+	android.AssertBoolEquals(t, "original library should be linked with non-stub variant", true, hasDirectDependency(t, ctx, libfoo, libbar))
+	android.AssertBoolEquals(t, "Stub library from API surface should be not linked with non-stub variant", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+
+	libfooVendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
+	libbarApiImportVendor := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
+
+	android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfooVendor, libbar))
+	android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfooVendor, libbarApiImportVendor))
 }
 
 func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
@@ -76,11 +83,13 @@
 		cc_library {
 			name: "libfoo",
 			shared_libs: ["libbar"],
+			vendor: true,
 		}
 
 		cc_api_library {
 			name: "libbar",
 			src: "libbar.so",
+			vendor_available: true,
 		}
 
 		api_imports {
@@ -88,14 +97,13 @@
 			shared_libs: [
 				"libbar",
 			],
-			header_libs: [],
 		}
 	`
 
 	ctx := prepareForCcTest.RunTestWithBp(t, bp)
 
-	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
-	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+	libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
+	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
 
 	android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
 }
@@ -105,143 +113,36 @@
 		cc_library {
 			name: "libfoo",
 			shared_libs: ["libbar"],
+			vendor_available: true,
 		}
 
 		cc_library {
 			name: "libbar",
+			vendor_available: true,
 		}
 
 		cc_api_library {
 			name: "libbar",
 			src: "libbar.so",
+			vendor_available: true,
 		}
 
 		api_imports {
 			name: "api_imports",
 			shared_libs: [],
-			header_libs: [],
 		}
 	`
 
 	ctx := prepareForCcTest.RunTestWithBp(t, bp)
 
-	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
-	libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
-	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+	libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
+	libbar := ctx.ModuleForTests("libbar", "android_vendor.29_arm64_armv8-a_shared").Module()
+	libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
 
 	android.AssertBoolEquals(t, "original library should be linked", true, hasDirectDependency(t, ctx, libfoo, libbar))
 	android.AssertBoolEquals(t, "Stub library from API surface should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
 }
 
-func TestApiHeaderReplacesExistingModule(t *testing.T) {
-	bp := `
-		cc_library {
-			name: "libfoo",
-			header_libs: ["libfoo_headers"],
-		}
-
-		cc_api_library {
-			name: "libfoo",
-			header_libs: ["libfoo_headers"],
-			src: "libfoo.so",
-		}
-
-		cc_library_headers {
-			name: "libfoo_headers",
-		}
-
-		cc_api_headers {
-			name: "libfoo_headers",
-		}
-
-		api_imports {
-			name: "api_imports",
-			shared_libs: [
-				"libfoo",
-			],
-			header_libs: [
-				"libfoo_headers",
-			],
-		}
-	`
-
-	ctx := prepareForCcTest.RunTestWithBp(t, bp)
-
-	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
-	libfooApiImport := ctx.ModuleForTests("libfoo.apiimport", "android_arm64_armv8-a_shared").Module()
-	libfooHeader := ctx.ModuleForTests("libfoo_headers", "android_arm64_armv8-a").Module()
-	libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
-
-	android.AssertBoolEquals(t, "original header should not be used for original library", false, hasDirectDependency(t, ctx, libfoo, libfooHeader))
-	android.AssertBoolEquals(t, "Header from API surface should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
-	android.AssertBoolEquals(t, "original header should not be used for library imported from API surface", false, hasDirectDependency(t, ctx, libfooApiImport, libfooHeader))
-	android.AssertBoolEquals(t, "Header from API surface should be used for library imported from API surface", true, hasDirectDependency(t, ctx, libfooApiImport, libfooHeaderApiImport))
-}
-
-func TestApiHeadersDoNotRequireOriginalModule(t *testing.T) {
-	bp := `
-	cc_library {
-		name: "libfoo",
-		header_libs: ["libfoo_headers"],
-	}
-
-	cc_api_headers {
-		name: "libfoo_headers",
-	}
-
-	api_imports {
-		name: "api_imports",
-		shared_libs: [
-			"libfoo",
-		],
-		header_libs: [
-			"libfoo_headers",
-		],
-	}
-	`
-
-	ctx := prepareForCcTest.RunTestWithBp(t, bp)
-
-	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
-	libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
-
-	android.AssertBoolEquals(t, "Header from API surface should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
-}
-
-func TestApiHeadersShouldNotReplaceWithoutApiImport(t *testing.T) {
-	bp := `
-		cc_library {
-			name: "libfoo",
-			header_libs: ["libfoo_headers"],
-		}
-
-		cc_library_headers {
-			name: "libfoo_headers",
-		}
-
-		cc_api_headers {
-			name: "libfoo_headers",
-		}
-
-		api_imports {
-			name: "api_imports",
-			shared_libs: [
-				"libfoo",
-			],
-			header_libs: [],
-		}
-	`
-
-	ctx := prepareForCcTest.RunTestWithBp(t, bp)
-
-	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
-	libfooHeader := ctx.ModuleForTests("libfoo_headers", "android_arm64_armv8-a").Module()
-	libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
-
-	android.AssertBoolEquals(t, "original header should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeader))
-	android.AssertBoolEquals(t, "Header from API surface should not be used for original library", false, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
-}
-
 func TestExportDirFromStubLibrary(t *testing.T) {
 	bp := `
 		cc_library {
@@ -330,7 +231,7 @@
 	android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
 
 	binFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
-	android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar_llndk.so")
+	android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar.llndk.apiimport.so")
 
 	binFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
 	android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", binFooCFlags, "-Ilibbar_llndk_include")
@@ -354,6 +255,17 @@
 			stl: "c++_shared",
 		}
 
+		cc_binary {
+			name: "binqux",
+			srcs: ["binfoo.cc"],
+			shared_libs: ["libbar"],
+		}
+
+		cc_library {
+			name: "libbar",
+			srcs: ["libbar.cc"],
+		}
+
 		cc_api_library {
 			name: "libbar",
 			// TODO(b/244244438) Remove src property once all variants are implemented.
@@ -417,10 +329,14 @@
 	android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
 
 	binFooLibFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("ld").Args["libFlags"]
-	android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar_ndk_29.so")
+	android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar.ndk.29.apiimport.so")
 
 	binFooCFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("cc").Args["cFlags"]
 	android.AssertStringDoesContain(t, "Binary using sdk should include headers from the NDK variant source", binFooCFlags, "-Ilibbar_ndk_29_include")
+
+	binQux := ctx.ModuleForTests("binqux", "android_arm64_armv8-a").Module()
+	android.AssertBoolEquals(t, "NDK Stub library from API surface should not be linked with nonSdk binary", false,
+		(hasDirectDependency(t, ctx, binQux, libbarApiImportv30) || hasDirectDependency(t, ctx, binQux, libbarApiImportv29)))
 }
 
 func TestApiLibraryWithMultipleVariants(t *testing.T) {
@@ -440,6 +356,11 @@
 			shared_libs: ["libbar"],
 		}
 
+		cc_library {
+			name: "libbar",
+			srcs: ["libbar.cc"],
+		}
+
 		cc_api_library {
 			name: "libbar",
 			// TODO(b/244244438) Remove src property once all variants are implemented.
@@ -450,6 +371,9 @@
 				"ndk.29",
 				"ndk.30",
 				"ndk.current",
+				"apex.29",
+				"apex.30",
+				"apex.current",
 			],
 		}
 
@@ -479,6 +403,30 @@
 
 		cc_api_variant {
 			name: "libbar",
+			variant: "apex",
+			version: "29",
+			src: "libbar_apex_29.so",
+			export_include_dirs: ["libbar_apex_29_include"]
+		}
+
+		cc_api_variant {
+			name: "libbar",
+			variant: "apex",
+			version: "30",
+			src: "libbar_apex_30.so",
+			export_include_dirs: ["libbar_apex_30_include"]
+		}
+
+		cc_api_variant {
+			name: "libbar",
+			variant: "apex",
+			version: "current",
+			src: "libbar_apex_current.so",
+			export_include_dirs: ["libbar_apex_current_include"]
+		}
+
+		cc_api_variant {
+			name: "libbar",
 			variant: "llndk",
 			src: "libbar_llndk.so",
 			export_include_dirs: ["libbar_llndk_include"]
@@ -489,7 +437,9 @@
 			shared_libs: [
 				"libbar",
 			],
-			header_libs: [],
+			apex_shared_libs: [
+				"libbar",
+			],
 		}
 	`
 	ctx := prepareForCcTest.RunTestWithBp(t, bp)
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index bb517ea..5b7ba43 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -352,6 +352,7 @@
 	Static_library         bazel.LabelAttribute
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
+	Alwayslink             bazel.BoolAttribute
 }
 
 // TODO(b/228623543): The below is not entirely true until the bug is fixed. For now, both targets are always generated
@@ -389,6 +390,11 @@
 
 	tags := android.ApexAvailableTags(module)
 	ctx.CreateBazelTargetModuleWithRestrictions(props, android.CommonAttributes{Name: name, Tags: tags}, attrs, prebuiltAttrs.Enabled)
+
+	_true := true
+	alwayslinkAttrs := *attrs
+	alwayslinkAttrs.Alwayslink.SetValue(&_true)
+	ctx.CreateBazelTargetModuleWithRestrictions(props, android.CommonAttributes{Name: name + "_alwayslink", Tags: tags}, &alwayslinkAttrs, prebuiltAttrs.Enabled)
 }
 
 type bazelPrebuiltLibrarySharedAttributes struct {
diff --git a/cc/sdk.go b/cc/sdk.go
index 23dd0cb..4f361eb 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -62,21 +62,26 @@
 		} else if isCcModule && ccModule.isImportedApiLibrary() {
 			apiLibrary, _ := ccModule.linker.(*apiLibraryDecorator)
 			if apiLibrary.hasNDKStubs() && ccModule.canUseSdk() {
+				variations := []string{"sdk"}
+				if apiLibrary.hasApexStubs() {
+					variations = append(variations, "")
+				}
 				// Handle cc_api_library module with NDK stubs and variants only which can use SDK
-				modules := ctx.CreateVariations("", "sdk")
-
+				modules := ctx.CreateVariations(variations...)
 				// Mark the SDK variant.
-				modules[1].(*Module).Properties.IsSdkVariant = true
-				// SDK variant is not supposed to be installed
-				modules[1].(*Module).Properties.PreventInstall = true
-
+				modules[0].(*Module).Properties.IsSdkVariant = true
 				if ctx.Config().UnbundledBuildApps() {
-					// For an unbundled apps build, hide the platform variant from Make.
-					modules[0].(*Module).Properties.HideFromMake = true
+					if apiLibrary.hasApexStubs() {
+						// For an unbundled apps build, hide the platform variant from Make.
+						modules[1].(*Module).Properties.HideFromMake = true
+						modules[1].(*Module).Properties.PreventInstall = true
+					}
 				} else {
 					// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
 					// exposed to Make.
-					modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
+					modules[0].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
+					// SDK variant is not supposed to be installed
+					modules[0].(*Module).Properties.PreventInstall = true
 				}
 			} else {
 				ccModule.Properties.Sdk_version = nil
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0ffedf6..e0a0629 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -293,12 +293,6 @@
 	isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(moduleName(ctx))
 
 	bootImage := defaultBootImageConfig(ctx)
-	// When `global.PreoptWithUpdatableBcp` is true, `bcpForDexpreopt` below includes the mainline
-	// boot jars into bootclasspath, so we should include the mainline boot image as well because it's
-	// generated from those jars.
-	if global.PreoptWithUpdatableBcp {
-		bootImage = mainlineBootImageConfig(ctx)
-	}
 	dexFiles, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp)
 
 	targets := ctx.MultiTargets()
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 117b660..76c78cb 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -44,8 +44,6 @@
 	bootImageConfigRawKey  = android.NewOnceKey("bootImageConfigRaw")
 	artBootImageName       = "art"
 	frameworkBootImageName = "boot"
-	mainlineBootImageName  = "mainline"
-	bootImageStem          = "boot"
 )
 
 func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig {
@@ -54,16 +52,14 @@
 
 		artModules := global.ArtApexJars
 		frameworkModules := global.BootJars.RemoveList(artModules)
-		mainlineBcpModules := global.ApexBootJars
-		frameworkSubdir := "system/framework"
 
 		// ART config for the primary boot image in the ART apex.
 		// It includes the Core Libraries.
 		artCfg := bootImageConfig{
 			name:                     artBootImageName,
-			stem:                     bootImageStem,
+			stem:                     "boot",
 			installDirOnHost:         "apex/art_boot_images/javalib",
-			installDirOnDevice:       frameworkSubdir,
+			installDirOnDevice:       "system/framework",
 			profileInstallPathInApex: "etc/boot-image.prof",
 			modules:                  artModules,
 			preloadedClassesFile:     "art/build/boot/preloaded-classes",
@@ -72,10 +68,11 @@
 
 		// Framework config for the boot image extension.
 		// It includes framework libraries and depends on the ART config.
+		frameworkSubdir := "system/framework"
 		frameworkCfg := bootImageConfig{
 			extends:              &artCfg,
 			name:                 frameworkBootImageName,
-			stem:                 bootImageStem,
+			stem:                 "boot",
 			installDirOnHost:     frameworkSubdir,
 			installDirOnDevice:   frameworkSubdir,
 			modules:              frameworkModules,
@@ -83,20 +80,9 @@
 			compilerFilter:       "speed-profile",
 		}
 
-		mainlineCfg := bootImageConfig{
-			extends:            &frameworkCfg,
-			name:               mainlineBootImageName,
-			stem:               bootImageStem,
-			installDirOnHost:   frameworkSubdir,
-			installDirOnDevice: frameworkSubdir,
-			modules:            mainlineBcpModules,
-			compilerFilter:     "verify",
-		}
-
 		return map[string]*bootImageConfig{
 			artBootImageName:       &artCfg,
 			frameworkBootImageName: &frameworkCfg,
-			mainlineBootImageName:  &mainlineCfg,
 		}
 	}).(map[string]*bootImageConfig)
 }
@@ -188,10 +174,6 @@
 	return genBootImageConfigs(ctx)[frameworkBootImageName]
 }
 
-func mainlineBootImageConfig(ctx android.PathContext) *bootImageConfig {
-	return genBootImageConfigs(ctx)[mainlineBootImageName]
-}
-
 // Apex boot config allows to access build/install paths of apex boot jars without going
 // through the usual trouble of registering dependencies on those modules and extracting build paths
 // from those dependencies.
diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go
index cd7f295..b704d09 100644
--- a/java/dexpreopt_config_test.go
+++ b/java/dexpreopt_config_test.go
@@ -28,10 +28,8 @@
 
 	result := android.GroupFixturePreparers(
 		PrepareForBootImageConfigTest,
-		PrepareApexBootJarConfigs,
 	).RunTest(t)
 
 	CheckArtBootImageConfig(t, result)
 	CheckFrameworkBootImageConfig(t, result)
-	CheckMainlineBootImageConfig(t, result)
 }
diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go
index c27f4c6..c509c1b 100644
--- a/java/dexpreopt_config_testing.go
+++ b/java/dexpreopt_config_testing.go
@@ -39,78 +39,6 @@
 	FixtureConfigureBootJars("com.android.art:core1", "com.android.art:core2", "platform:framework"),
 )
 
-var PrepareApexBootJarConfigs = FixtureConfigureApexBootJars(
-	"com.android.foo:framework-foo", "com.android.bar:framework-bar")
-
-var PrepareApexBootJarConfigsAndModules = android.GroupFixturePreparers(
-	PrepareApexBootJarConfigs,
-	prepareApexBootJarModule("com.android.foo", "framework-foo"),
-	prepareApexBootJarModule("com.android.bar", "framework-bar"),
-)
-
-var ApexBootJarFragmentsForPlatformBootclasspath = fmt.Sprintf(`
-	{
-		apex: "%[1]s",
-		module: "%[1]s-bootclasspathfragment",
-	},
-	{
-		apex: "%[2]s",
-		module: "%[2]s-bootclasspathfragment",
-	},
-`, "com.android.foo", "com.android.bar")
-
-var ApexBootJarDexJarPaths = []string{
-	"out/soong/.intermediates/packages/modules/com.android.bar/framework-bar/android_common_apex10000/aligned/framework-bar.jar",
-	"out/soong/.intermediates/packages/modules/com.android.foo/framework-foo/android_common_apex10000/aligned/framework-foo.jar",
-}
-
-func prepareApexBootJarModule(apexName string, moduleName string) android.FixturePreparer {
-	moduleSourceDir := fmt.Sprintf("packages/modules/%s", apexName)
-	return android.GroupFixturePreparers(
-		android.FixtureAddTextFile(moduleSourceDir+"/Android.bp", fmt.Sprintf(`
-			apex {
-				name: "%[1]s",
-				key: "%[1]s.key",
-				bootclasspath_fragments: [
-					"%[1]s-bootclasspathfragment",
-				],
-				updatable: false,
-			}
-
-			apex_key {
-				name: "%[1]s.key",
-				public_key: "%[1]s.avbpubkey",
-				private_key: "%[1]s.pem",
-			}
-
-			bootclasspath_fragment {
-				name: "%[1]s-bootclasspathfragment",
-				contents: ["%[2]s"],
-				apex_available: ["%[1]s"],
-				hidden_api: {
-					split_packages: ["*"],
-				},
-			}
-
-			java_library {
-				name: "%[2]s",
-				srcs: ["%[2]s.java"],
-				system_modules: "none",
-				sdk_version: "none",
-				compile_dex: true,
-				apex_available: ["%[1]s"],
-			}
-		`, apexName, moduleName)),
-		android.FixtureMergeMockFs(android.MockFS{
-			fmt.Sprintf("%s/apex_manifest.json", moduleSourceDir):          nil,
-			fmt.Sprintf("%s/%s.avbpubkey", moduleSourceDir, apexName):      nil,
-			fmt.Sprintf("%s/%s.pem", moduleSourceDir, apexName):            nil,
-			fmt.Sprintf("system/sepolicy/apex/%s-file_contexts", apexName): nil,
-			fmt.Sprintf("%s/%s.java", moduleSourceDir, moduleName):         nil,
-		}),
-	)
-}
-
 // normalizedInstall represents a android.RuleBuilderInstall that has been normalized to remove
 // test specific parts of the From path.
 type normalizedInstall struct {
@@ -673,366 +601,6 @@
 	checkBootImageConfig(t, imageConfig, mutated, expected)
 }
 
-// getMainlineImageConfig gets the framework bootImageConfig that was created during the test.
-func getMainlineImageConfig(result *android.TestResult) *bootImageConfig {
-	pathCtx := &android.TestPathContext{TestResult: result}
-	imageConfig := mainlineBootImageConfig(pathCtx)
-	return imageConfig
-}
-
-// CheckMainlineBootImageConfig checks the status of the fields of the bootImageConfig and
-// bootImageVariant structures that are returned from mainlineBootImageConfig.
-//
-// This is before any fields are mutated.
-func CheckMainlineBootImageConfig(t *testing.T, result *android.TestResult) {
-	expectedLicenseMetadataFile := ""
-	imageConfig := getMainlineImageConfig(result)
-
-	expected := &expectedConfig{
-		name:                     "mainline",
-		stem:                     "boot",
-		dir:                      "out/soong/test_device/dex_mainlinejars",
-		symbolsDir:               "out/soong/test_device/dex_mainlinejars_unstripped",
-		installDirOnDevice:       "system/framework",
-		installDirOnHost:         "system/framework",
-		profileInstallPathInApex: "",
-		modules: android.CreateTestConfiguredJarList([]string{
-			"com.android.foo:framework-foo",
-			"com.android.bar:framework-bar",
-		}),
-		dexPaths: []string{
-			"out/soong/test_device/dex_mainlinejars_input/framework-foo.jar",
-			"out/soong/test_device/dex_mainlinejars_input/framework-bar.jar",
-		},
-		dexPathsDeps: []string{
-			"out/soong/test_device/dex_artjars_input/core1.jar",
-			"out/soong/test_device/dex_artjars_input/core2.jar",
-			"out/soong/test_device/dex_bootjars_input/framework.jar",
-			"out/soong/test_device/dex_mainlinejars_input/framework-foo.jar",
-			"out/soong/test_device/dex_mainlinejars_input/framework-bar.jar",
-		},
-		zip: "out/soong/test_device/dex_mainlinejars/mainline.zip",
-		variants: []*expectedVariant{
-			{
-				archType: android.Arm64,
-				dexLocations: []string{
-					"/apex/com.android.foo/javalib/framework-foo.jar",
-					"/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				dexLocationsDeps: []string{
-					"/apex/com.android.art/javalib/core1.jar",
-					"/apex/com.android.art/javalib/core2.jar",
-					"/system/framework/framework.jar",
-					"/apex/com.android.foo/javalib/framework-foo.jar",
-					"/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				imagePathOnHost:   "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art",
-				imagePathOnDevice: "/system/framework/arm64/boot-framework-foo.art",
-				imagesDeps: []string{
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex",
-				},
-				baseImages: []string{
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art",
-				},
-				baseImagesDeps: []string{
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex",
-				},
-				installs: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art",
-						to:   "/system/framework/arm64/boot-framework-foo.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat",
-						to:   "/system/framework/arm64/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art",
-						to:   "/system/framework/arm64/boot-framework-bar.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat",
-						to:   "/system/framework/arm64/boot-framework-bar.oat",
-					},
-				},
-				vdexInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex",
-						to:   "/system/framework/arm64/boot-framework-foo.vdex",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex",
-						to:   "/system/framework/arm64/boot-framework-bar.vdex",
-					},
-				},
-				unstrippedInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-foo.oat",
-						to:   "/system/framework/arm64/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-bar.oat",
-						to:   "/system/framework/arm64/boot-framework-bar.oat",
-					},
-				},
-				licenseMetadataFile: expectedLicenseMetadataFile,
-			},
-			{
-				archType: android.Arm,
-				dexLocations: []string{
-					"/apex/com.android.foo/javalib/framework-foo.jar",
-					"/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				dexLocationsDeps: []string{
-					"/apex/com.android.art/javalib/core1.jar",
-					"/apex/com.android.art/javalib/core2.jar",
-					"/system/framework/framework.jar",
-					"/apex/com.android.foo/javalib/framework-foo.jar",
-					"/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				imagePathOnHost:   "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art",
-				imagePathOnDevice: "/system/framework/arm/boot-framework-foo.art",
-				imagesDeps: []string{
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat",
-					"out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex",
-				},
-				baseImages: []string{
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art",
-				},
-				baseImagesDeps: []string{
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
-					"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat",
-					"out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex",
-				},
-				installs: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art",
-						to:   "/system/framework/arm/boot-framework-foo.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat",
-						to:   "/system/framework/arm/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art",
-						to:   "/system/framework/arm/boot-framework-bar.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat",
-						to:   "/system/framework/arm/boot-framework-bar.oat",
-					},
-				},
-				vdexInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex",
-						to:   "/system/framework/arm/boot-framework-foo.vdex",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex",
-						to:   "/system/framework/arm/boot-framework-bar.vdex",
-					},
-				},
-				unstrippedInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-foo.oat",
-						to:   "/system/framework/arm/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-bar.oat",
-						to:   "/system/framework/arm/boot-framework-bar.oat",
-					},
-				},
-				licenseMetadataFile: expectedLicenseMetadataFile,
-			},
-			{
-				archType: android.X86_64,
-				dexLocations: []string{
-					"host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
-					"host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				dexLocationsDeps: []string{
-					"host/linux-x86/apex/com.android.art/javalib/core1.jar",
-					"host/linux-x86/apex/com.android.art/javalib/core2.jar",
-					"host/linux-x86/system/framework/framework.jar",
-					"host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
-					"host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				imagePathOnHost:   "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art",
-				imagePathOnDevice: "/system/framework/x86_64/boot-framework-foo.art",
-				imagesDeps: []string{
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex",
-				},
-				baseImages: []string{
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art",
-				},
-				baseImagesDeps: []string{
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex",
-				},
-				installs: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art",
-						to:   "/system/framework/x86_64/boot-framework-foo.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat",
-						to:   "/system/framework/x86_64/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art",
-						to:   "/system/framework/x86_64/boot-framework-bar.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat",
-						to:   "/system/framework/x86_64/boot-framework-bar.oat",
-					},
-				},
-				vdexInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex",
-						to:   "/system/framework/x86_64/boot-framework-foo.vdex",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex",
-						to:   "/system/framework/x86_64/boot-framework-bar.vdex",
-					},
-				},
-				unstrippedInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-foo.oat",
-						to:   "/system/framework/x86_64/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-bar.oat",
-						to:   "/system/framework/x86_64/boot-framework-bar.oat",
-					},
-				},
-				licenseMetadataFile: expectedLicenseMetadataFile,
-			},
-			{
-				archType: android.X86,
-				dexLocations: []string{
-					"host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
-					"host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				dexLocationsDeps: []string{
-					"host/linux-x86/apex/com.android.art/javalib/core1.jar",
-					"host/linux-x86/apex/com.android.art/javalib/core2.jar",
-					"host/linux-x86/system/framework/framework.jar",
-					"host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
-					"host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
-				},
-				imagePathOnHost:   "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art",
-				imagePathOnDevice: "/system/framework/x86/boot-framework-foo.art",
-				imagesDeps: []string{
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat",
-					"out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex",
-				},
-				baseImages: []string{
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art",
-				},
-				baseImagesDeps: []string{
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
-					"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat",
-					"out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex",
-				},
-				installs: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art",
-						to:   "/system/framework/x86/boot-framework-foo.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat",
-						to:   "/system/framework/x86/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art",
-						to:   "/system/framework/x86/boot-framework-bar.art",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat",
-						to:   "/system/framework/x86/boot-framework-bar.oat",
-					},
-				},
-				vdexInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex",
-						to:   "/system/framework/x86/boot-framework-foo.vdex",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex",
-						to:   "/system/framework/x86/boot-framework-bar.vdex",
-					},
-				},
-				unstrippedInstalls: []normalizedInstall{
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-foo.oat",
-						to:   "/system/framework/x86/boot-framework-foo.oat",
-					},
-					{
-						from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-bar.oat",
-						to:   "/system/framework/x86/boot-framework-bar.oat",
-					},
-				},
-				licenseMetadataFile: expectedLicenseMetadataFile,
-			},
-		},
-		profileInstalls:            []normalizedInstall{},
-		profileLicenseMetadataFile: expectedLicenseMetadataFile,
-	}
-
-	checkBootImageConfig(t, imageConfig, false, expected)
-}
-
 // clearMutatedFields clears fields in the expectedConfig that correspond to fields in the
 // bootImageConfig/bootImageVariant structs which are mutated outside the call to
 // genBootImageConfigs.
@@ -1144,10 +712,6 @@
 DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art:/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
 DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art:/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
 DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art:/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art:/system/framework/arm/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat:/system/framework/arm/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art:/system/framework/arm/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat:/system/framework/arm/boot-framework-bar.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art:/system/framework/arm64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art:/system/framework/arm64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat:/system/framework/arm64/boot-framework-bar.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art:/system/framework/x86/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art:/system/framework/x86/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat:/system/framework/x86/boot-framework-bar.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art:/system/framework/x86_64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art:/system/framework/x86_64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat:/system/framework/x86_64/boot-framework-bar.oat
 DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex
 DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex
 DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex
@@ -1156,10 +720,6 @@
 DEXPREOPT_IMAGE_DEPS_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex
 DEXPREOPT_IMAGE_DEPS_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex
 DEXPREOPT_IMAGE_DEPS_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex
 DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm=%[1]s
 DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm64=%[1]s
 DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86=%[1]s
@@ -1168,17 +728,11 @@
 DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
 DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
 DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
 DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEart=/system/framework/boot.art
 DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEboot=/system/framework/boot.art:/system/framework/boot-framework.art
-DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEmainline=/system/framework/boot.art:/system/framework/boot-framework.art:/system/framework/boot-framework-foo.art
 DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art
 DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art:out/soong/test_device/dex_bootjars/android/system/framework/boot-framework.art
-DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTmainline=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art:out/soong/test_device/dex_bootjars/android/system/framework/boot-framework.art:out/soong/test_device/dex_mainlinejars/android/system/framework/boot-framework-foo.art
-DEXPREOPT_IMAGE_NAMES=art boot mainline
+DEXPREOPT_IMAGE_NAMES=art boot
 DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/test_device/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof out/soong/test_device/dex_bootjars/boot.prof:/system/etc/boot-image.prof
 DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
 DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat
@@ -1189,10 +743,6 @@
 DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
 DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
 DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm=out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-foo.oat:/system/framework/arm/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-bar.oat:/system/framework/arm/boot-framework-bar.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm64=out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-bar.oat:/system/framework/arm64/boot-framework-bar.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86=out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-bar.oat:/system/framework/x86/boot-framework-bar.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-bar.oat:/system/framework/x86_64/boot-framework-bar.oat
 DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex
 DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex
 DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex
@@ -1201,13 +751,8 @@
 DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex:/system/framework/arm64/boot-framework.vdex
 DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex:/system/framework/x86/boot-framework.vdex
 DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex:/system/framework/x86_64/boot-framework.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex:/system/framework/arm/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex:/system/framework/arm/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex:/system/framework/arm64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex:/system/framework/arm64/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex:/system/framework/x86/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex:/system/framework/x86/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex:/system/framework/x86_64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex:/system/framework/x86_64/boot-framework-bar.vdex
 DEXPREOPT_IMAGE_ZIP_art=out/soong/test_device/dex_artjars/art.zip
 DEXPREOPT_IMAGE_ZIP_boot=out/soong/test_device/dex_bootjars/boot.zip
-DEXPREOPT_IMAGE_ZIP_mainline=out/soong/test_device/dex_mainlinejars/mainline.zip
 DEXPREOPT_IMAGE_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art
 DEXPREOPT_IMAGE_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art
 DEXPREOPT_IMAGE_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art
@@ -1216,10 +761,6 @@
 DEXPREOPT_IMAGE_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art
 DEXPREOPT_IMAGE_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art
 DEXPREOPT_IMAGE_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art
-DEXPREOPT_IMAGE_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art
-DEXPREOPT_IMAGE_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art
-DEXPREOPT_IMAGE_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art
-DEXPREOPT_IMAGE_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art
 `
 	expected := strings.TrimSpace(fmt.Sprintf(format, expectedLicenseMetadataFile))
 	actual := strings.TrimSpace(out.String())
diff --git a/java/java.go b/java/java.go
index a00e26f..6a764cf 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2838,7 +2838,7 @@
 
 		props = bazel.BazelTargetModuleProperties{
 			Rule_class:        "kt_jvm_library",
-			Bzl_load_location: "@rules_kotlin//kotlin:jvm_library.bzl",
+			Bzl_load_location: "//build/bazel/rules/kotlin:kt_jvm_library.bzl",
 		}
 	}
 
@@ -2933,14 +2933,15 @@
 		ktName := m.Name() + "_kt"
 		ktProps := bazel.BazelTargetModuleProperties{
 			Rule_class:        "kt_jvm_library",
-			Bzl_load_location: "@rules_kotlin//kotlin:jvm_library.bzl",
+			Bzl_load_location: "//build/bazel/rules/kotlin:kt_jvm_library.bzl",
 		}
 		ktAttrs := &javaLibraryAttributes{
 			Deps: deps,
 			javaCommonAttributes: &javaCommonAttributes{
-				Srcs:      commonAttrs.Srcs,
-				Plugins:   commonAttrs.Plugins,
-				Javacopts: commonAttrs.Javacopts,
+				Srcs:                    commonAttrs.Srcs,
+				Plugins:                 commonAttrs.Plugins,
+				Javacopts:               commonAttrs.Javacopts,
+				javaResourcesAttributes: commonAttrs.javaResourcesAttributes,
 			},
 		}
 
@@ -2948,19 +2949,6 @@
 			ktAttrs.javaCommonAttributes.Common_srcs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Common_srcs))
 		}
 
-		// kt_jvm_library does not support resource_strip_prefix, if this attribute
-		// is set, than javaResourcesAttributes needs to be set in the
-		// javaCommonAttributes of the java_binary target
-		if commonAttrs.javaResourcesAttributes != nil {
-			if commonAttrs.javaResourcesAttributes.Resource_strip_prefix != nil {
-				attrs.javaCommonAttributes = &javaCommonAttributes{
-					javaResourcesAttributes: commonAttrs.javaResourcesAttributes,
-				}
-			} else {
-				ktAttrs.javaCommonAttributes.javaResourcesAttributes = commonAttrs.javaResourcesAttributes
-			}
-		}
-
 		ctx.CreateBazelTargetModule(ktProps, android.CommonAttributes{Name: ktName}, ktAttrs)
 		attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + ktName}})
 	}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 0ea3609..5824f08 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -414,7 +414,6 @@
 	frameworkBootImageConfig := defaultBootImageConfig(ctx)
 	bootFrameworkProfileRule(ctx, frameworkBootImageConfig)
 	b.generateBootImage(ctx, frameworkBootImageName, platformModules)
-	b.generateBootImage(ctx, mainlineBootImageName, apexModules)
 	b.copyApexBootJarsForAppsDexpreopt(ctx, apexModules)
 	dumpOatRules(ctx, frameworkBootImageConfig)
 }
diff --git a/multitree/api_imports.go b/multitree/api_imports.go
index 6674d3e..07ec7bc 100644
--- a/multitree/api_imports.go
+++ b/multitree/api_imports.go
@@ -40,8 +40,9 @@
 }
 
 type apiImportsProperties struct {
-	Shared_libs []string // List of C shared libraries from API surfaces
-	Header_libs []string // List of C header libraries from API surfaces
+	Shared_libs      []string // List of C shared libraries from API surfaces
+	Header_libs      []string // List of C header libraries from API surfaces
+	Apex_shared_libs []string // List of C shared libraries with APEX stubs
 }
 
 // 'api_imports' is a module which describes modules available from API surfaces.
@@ -60,7 +61,7 @@
 }
 
 type ApiImportInfo struct {
-	SharedLibs, HeaderLibs map[string]string
+	SharedLibs, HeaderLibs, ApexSharedLibs map[string]string
 }
 
 var ApiImportsProvider = blueprint.NewMutatorProvider(ApiImportInfo{}, "deps")
@@ -78,10 +79,12 @@
 
 	sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
 	headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
+	apexSharedLibs := generateNameMapWithSuffix(imports.properties.Apex_shared_libs)
 
 	ctx.SetProvider(ApiImportsProvider, ApiImportInfo{
-		SharedLibs: sharedLibs,
-		HeaderLibs: headerLibs,
+		SharedLibs:     sharedLibs,
+		HeaderLibs:     headerLibs,
+		ApexSharedLibs: apexSharedLibs,
 	})
 }
 
diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py
index 3d7c0fa..2ce0ee2 100644
--- a/scripts/conv_linker_config.py
+++ b/scripts/conv_linker_config.py
@@ -28,14 +28,15 @@
 
 def Proto(args):
     pb = linker_config_pb2.LinkerConfig()
-    for input in args.source.split(':'):
-        json_content = ''
-        with open(input) as f:
-            for line in f:
-                if not line.lstrip().startswith('//'):
-                    json_content += line
-        obj = json.loads(json_content, object_pairs_hook=collections.OrderedDict)
-        ParseDict(obj, pb)
+    if args.source:
+        for input in args.source.split(':'):
+            json_content = ''
+            with open(input) as f:
+                for line in f:
+                    if not line.lstrip().startswith('//'):
+                        json_content += line
+            obj = json.loads(json_content, object_pairs_hook=collections.OrderedDict)
+            ParseDict(obj, pb)
     with open(args.output, 'wb') as f:
         f.write(pb.SerializeToString())
 
@@ -104,7 +105,7 @@
     parser_proto.add_argument(
         '-s',
         '--source',
-        required=True,
+        nargs='?',
         type=str,
         help='Colon-separated list of linker configuration files in JSON.')
     parser_proto.add_argument(
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index efb97be..d81635e 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -27,11 +27,6 @@
 // fixtureAddPlatformBootclasspathForBootclasspathFragment adds a platform_bootclasspath module that
 // references the bootclasspath fragment.
 func fixtureAddPlatformBootclasspathForBootclasspathFragment(apex, fragment string) android.FixturePreparer {
-	return fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra(apex, fragment, "")
-}
-
-// fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra is the same as above, but also adds extra fragments.
-func fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra(apex, fragment, extraFragments string) android.FixturePreparer {
 	return android.GroupFixturePreparers(
 		// Add a platform_bootclasspath module.
 		android.FixtureAddTextFile("frameworks/base/boot/Android.bp", fmt.Sprintf(`
@@ -42,10 +37,9 @@
 						apex: "%s",
 						module: "%s",
 					},
-					%s
 				],
 			}
-		`, apex, fragment, extraFragments)),
+		`, apex, fragment)),
 		android.FixtureAddFile("frameworks/base/config/boot-profile.txt", nil),
 		android.FixtureAddFile("frameworks/base/config/boot-image-profile.txt", nil),
 		android.FixtureAddFile("build/soong/scripts/check_boot_jars/package_allowed_list.txt", nil),
@@ -85,11 +79,9 @@
 		}),
 
 		// Add a platform_bootclasspath that depends on the fragment.
-		fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra(
-			"com.android.art", "mybootclasspathfragment", java.ApexBootJarFragmentsForPlatformBootclasspath),
+		fixtureAddPlatformBootclasspathForBootclasspathFragment("com.android.art", "mybootclasspathfragment"),
 
 		java.PrepareForBootImageConfigTest,
-		java.PrepareApexBootJarConfigsAndModules,
 		android.FixtureWithRootAndroidBp(`
 			sdk {
 				name: "mysdk",
@@ -204,15 +196,9 @@
 		snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) {
 			// Make sure that the boot jars package check rule includes the dex jars retrieved from the prebuilt apex.
 			checkBootJarsPackageCheckRule(t, result,
-				append(
-					[]string{
-						"out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core1.jar",
-						"out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core2.jar",
-						"out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar",
-					},
-					java.ApexBootJarDexJarPaths...,
-				)...,
-			)
+				"out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core1.jar",
+				"out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core2.jar",
+				"out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar")
 			java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/snapshot/mybootclasspathfragment/android_common_com.android.art/meta_lic")
 			java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic")
 		}),
@@ -236,15 +222,9 @@
 
 	// Make sure that the boot jars package check rule includes the dex jars created from the source.
 	checkBootJarsPackageCheckRule(t, result,
-		append(
-			[]string{
-				"out/soong/.intermediates/core1/android_common_apex10000/aligned/core1.jar",
-				"out/soong/.intermediates/core2/android_common_apex10000/aligned/core2.jar",
-				"out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar",
-			},
-			java.ApexBootJarDexJarPaths...,
-		)...,
-	)
+		"out/soong/.intermediates/core1/android_common_apex10000/aligned/core1.jar",
+		"out/soong/.intermediates/core2/android_common_apex10000/aligned/core2.jar",
+		"out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar")
 }
 
 // checkBootJarsPackageCheckRule checks that the supplied module is an input to the boot jars