Merge "Switch to toybox mv(1)."
diff --git a/android/apex.go b/android/apex.go
index 8d99d56..a93baf6 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -178,8 +178,16 @@
 	return false
 }
 
+type hostContext interface {
+	Host() bool
+}
+
 // Tests whether a module named moduleName is directly depended on by any APEX.
-func DirectlyInAnyApex(moduleName string) bool {
+func DirectlyInAnyApex(ctx hostContext, moduleName string) bool {
+	if ctx.Host() {
+		// Host has no APEX.
+		return false
+	}
 	apexNamesMapMutex.Lock()
 	defer apexNamesMapMutex.Unlock()
 	if apexNames, ok := apexNamesMap()[moduleName]; ok {
diff --git a/android/arch.go b/android/arch.go
index e8d9c6e..0180b87 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -103,21 +103,217 @@
 }
 */
 
-var archVariants = map[ArchType][]string{}
-var archFeatures = map[ArchType][]string{}
-var archFeatureMap = map[ArchType]map[string][]string{}
+var archVariants = map[ArchType][]string{
+	Arm: {
+		"armv7-a",
+		"armv7-a-neon",
+		"armv8-a",
+		"armv8-2a",
+		"cortex-a7",
+		"cortex-a8",
+		"cortex-a9",
+		"cortex-a15",
+		"cortex-a53",
+		"cortex-a53-a57",
+		"cortex-a55",
+		"cortex-a72",
+		"cortex-a73",
+		"cortex-a75",
+		"cortex-a76",
+		"krait",
+		"kryo",
+		"kryo385",
+		"exynos-m1",
+		"exynos-m2",
+	},
+	Arm64: {
+		"armv8_a",
+		"armv8_2a",
+		"cortex-a53",
+		"cortex-a55",
+		"cortex-a72",
+		"cortex-a73",
+		"cortex-a75",
+		"cortex-a76",
+		"kryo",
+		"kryo385",
+		"exynos-m1",
+		"exynos-m2",
+	},
+	Mips: {
+		"mips32_fp",
+		"mips32r2_fp",
+		"mips32r2_fp_xburst",
+		"mips32r2dsp_fp",
+		"mips32r2dspr2_fp",
+		"mips32r6",
+	},
+	Mips64: {
+		"mips64r2",
+		"mips64r6",
+	},
+	X86: {
+		"atom",
+		"haswell",
+		"ivybridge",
+		"sandybridge",
+		"silvermont",
+		"x86_64",
+	},
+	X86_64: {
+		"haswell",
+		"ivybridge",
+		"sandybridge",
+		"silvermont",
+	},
+}
+
+var archFeatures = map[ArchType][]string{
+	Arm: {
+		"neon",
+	},
+	Mips: {
+		"dspr2",
+		"rev6",
+		"msa",
+	},
+	Mips64: {
+		"rev6",
+		"msa",
+	},
+	X86: {
+		"ssse3",
+		"sse4",
+		"sse4_1",
+		"sse4_2",
+		"aes_ni",
+		"avx",
+		"popcnt",
+		"movbe",
+	},
+	X86_64: {
+		"ssse3",
+		"sse4",
+		"sse4_1",
+		"sse4_2",
+		"aes_ni",
+		"avx",
+		"popcnt",
+	},
+}
+
+var archFeatureMap = map[ArchType]map[string][]string{
+	Arm: {
+		"armv7-a-neon": {
+			"neon",
+		},
+		"armv8-a": {
+			"neon",
+		},
+		"armv8-2a": {
+			"neon",
+		},
+	},
+	Mips: {
+		"mips32r2dspr2_fp": {
+			"dspr2",
+		},
+		"mips32r6": {
+			"rev6",
+		},
+	},
+	Mips64: {
+		"mips64r6": {
+			"rev6",
+		},
+	},
+	X86: {
+		"atom": {
+			"ssse3",
+			"movbe",
+		},
+		"haswell": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"avx",
+			"popcnt",
+			"movbe",
+		},
+		"ivybridge": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"avx",
+			"popcnt",
+		},
+		"sandybridge": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"popcnt",
+		},
+		"silvermont": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"popcnt",
+			"movbe",
+		},
+		"x86_64": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"popcnt",
+		},
+	},
+	X86_64: {
+		"haswell": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"avx",
+			"popcnt",
+		},
+		"ivybridge": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"avx",
+			"popcnt",
+		},
+		"sandybridge": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"popcnt",
+		},
+		"silvermont": {
+			"ssse3",
+			"sse4",
+			"sse4_1",
+			"sse4_2",
+			"aes_ni",
+			"popcnt",
+		},
+	},
+}
+
 var defaultArchFeatureMap = map[OsType]map[ArchType][]string{}
 
-func RegisterArchVariants(arch ArchType, variants ...string) {
-	checkCalledFromInit()
-	archVariants[arch] = append(archVariants[arch], variants...)
-}
-
-func RegisterArchFeatures(arch ArchType, features ...string) {
-	checkCalledFromInit()
-	archFeatures[arch] = append(archFeatures[arch], features...)
-}
-
 func RegisterDefaultArchVariantFeatures(os OsType, arch ArchType, features ...string) {
 	checkCalledFromInit()
 
@@ -133,24 +329,6 @@
 	defaultArchFeatureMap[os][arch] = features
 }
 
-func RegisterArchVariantFeatures(arch ArchType, variant string, features ...string) {
-	checkCalledFromInit()
-	if !InList(variant, archVariants[arch]) {
-		panic(fmt.Errorf("Invalid variant %q for arch %q", variant, arch))
-	}
-
-	for _, feature := range features {
-		if !InList(feature, archFeatures[arch]) {
-			panic(fmt.Errorf("Invalid feature %q for arch %q variant %q", feature, arch, variant))
-		}
-	}
-
-	if archFeatureMap[arch] == nil {
-		archFeatureMap[arch] = make(map[string][]string)
-	}
-	archFeatureMap[arch][variant] = features
-}
-
 // An Arch indicates a single CPU architecture.
 type Arch struct {
 	ArchType     ArchType
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 7844756..fa0017d 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -32,6 +32,9 @@
 	Name() string
 	Target() android.Target
 	subAndroidMk(*android.AndroidMkData, interface{})
+	Arch() android.Arch
+	Os() android.OsType
+	Host() bool
 	useVndk() bool
 	static() bool
 	inRecovery() bool
@@ -189,9 +192,9 @@
 			}
 		})
 	}
-
-	if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx.Name()) &&
-		!ctx.inRecovery() && !ctx.useVndk() && !ctx.static() {
+	if len(library.Properties.Stubs.Versions) > 0 &&
+		android.DirectlyInAnyApex(ctx, ctx.Name()) && !ctx.inRecovery() && !ctx.useVndk() &&
+		!ctx.static() {
 		if !library.buildStubs() {
 			ret.SubName = ".bootstrap"
 		}
diff --git a/cc/cc.go b/cc/cc.go
index 4717b72..c0bd11e 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -244,6 +244,10 @@
 	useSdk() bool
 	sdkVersion() string
 	useVndk() bool
+	isNdk() bool
+	isLlndk() bool
+	isLlndkPublic() bool
+	isVndkPrivate() bool
 	isVndk() bool
 	isVndkSp() bool
 	isVndkExt() bool
@@ -473,6 +477,25 @@
 	return c.Properties.UseVndk
 }
 
+func (c *Module) isNdk() bool {
+	return inList(c.Name(), ndkMigratedLibs)
+}
+
+func (c *Module) isLlndk() bool {
+	// Returns true for both LLNDK (public) and LLNDK-private libs.
+	return inList(c.Name(), llndkLibraries)
+}
+
+func (c *Module) isLlndkPublic() bool {
+	// Returns true only for LLNDK (public) libs.
+	return c.isLlndk() && !c.isVndkPrivate()
+}
+
+func (c *Module) isVndkPrivate() bool {
+	// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
+	return inList(c.Name(), vndkPrivateLibraries)
+}
+
 func (c *Module) isVndk() bool {
 	if vndkdep := c.vndkdep; vndkdep != nil {
 		return vndkdep.isVndk()
@@ -604,6 +627,22 @@
 	return ctx.mod.useVndk()
 }
 
+func (ctx *moduleContextImpl) isNdk() bool {
+	return ctx.mod.isNdk()
+}
+
+func (ctx *moduleContextImpl) isLlndk() bool {
+	return ctx.mod.isLlndk()
+}
+
+func (ctx *moduleContextImpl) isLlndkPublic() bool {
+	return ctx.mod.isLlndkPublic()
+}
+
+func (ctx *moduleContextImpl) isVndkPrivate() bool {
+	return ctx.mod.isVndkPrivate()
+}
+
 func (ctx *moduleContextImpl) isVndk() bool {
 	return ctx.mod.isVndk()
 }
@@ -642,16 +681,16 @@
 		// APEX variants do not need ABI dumps.
 		return false
 	}
-	if inList(ctx.baseModuleName(), llndkLibraries) {
+	if ctx.isNdk() {
 		return true
 	}
-	if inList(ctx.baseModuleName(), ndkMigratedLibs) {
+	if ctx.isLlndkPublic() {
 		return true
 	}
-	if ctx.useVndk() && ctx.isVndk() {
+	if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate() {
 		// Return true if this is VNDK-core, VNDK-SP, or VNDK-Ext and this is not
 		// VNDK-private.
-		return Bool(ctx.mod.VendorProperties.Vendor_available) || ctx.isVndkExt()
+		return true
 	}
 	return false
 }
@@ -874,7 +913,8 @@
 		// force anything in the make world to link against the stubs library.
 		// (unless it is explicitly referenced via .bootstrap suffix or the
 		// module is marked with 'bootstrap: true').
-		if c.HasStubsVariants() && android.DirectlyInAnyApex(ctx.baseModuleName()) &&
+		if c.HasStubsVariants() &&
+			android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) &&
 			!c.inRecovery() && !c.useVndk() && !c.static() && c.IsStubs() {
 			c.Properties.HideFromMake = false // unhide
 			// Note: this is still non-installable
@@ -1456,7 +1496,7 @@
 				depIsStubs := dependentLibrary.buildStubs()
 				depHasStubs := ccDep.HasStubsVariants()
 				depInSameApex := android.DirectlyInApex(c.ApexName(), depName)
-				depInPlatform := !android.DirectlyInAnyApex(depName)
+				depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
 
 				var useThisDep bool
 				if depIsStubs && explicitlyVersioned {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index f98e1be..1ca1656 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -86,20 +86,6 @@
 )
 
 func init() {
-	android.RegisterArchVariants(android.Arm64,
-		"armv8_a",
-		"armv8_2a",
-		"cortex-a53",
-		"cortex-a55",
-		"cortex-a72",
-		"cortex-a73",
-		"cortex-a75",
-		"cortex-a76",
-		"kryo",
-		"kryo385",
-		"exynos-m1",
-		"exynos-m2")
-
 	pctx.StaticVariable("arm64GccVersion", arm64GccVersion)
 
 	pctx.SourcePathVariable("Arm64GccRoot",
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 60bb91a..cd7c410 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -168,35 +168,6 @@
 )
 
 func init() {
-	android.RegisterArchFeatures(android.Arm,
-		"neon")
-
-	android.RegisterArchVariants(android.Arm,
-		"armv7-a",
-		"armv7-a-neon",
-		"armv8-a",
-		"armv8-2a",
-		"cortex-a7",
-		"cortex-a8",
-		"cortex-a9",
-		"cortex-a15",
-		"cortex-a53",
-		"cortex-a53-a57",
-		"cortex-a55",
-		"cortex-a72",
-		"cortex-a73",
-		"cortex-a75",
-		"cortex-a76",
-		"krait",
-		"kryo",
-		"kryo385",
-		"exynos-m1",
-		"exynos-m2")
-
-	android.RegisterArchVariantFeatures(android.Arm, "armv7-a-neon", "neon")
-	android.RegisterArchVariantFeatures(android.Arm, "armv8-a", "neon")
-	android.RegisterArchVariantFeatures(android.Arm, "armv8-2a", "neon")
-
 	pctx.StaticVariable("armGccVersion", armGccVersion)
 
 	pctx.SourcePathVariable("ArmGccRoot",
diff --git a/cc/config/mips64_device.go b/cc/config/mips64_device.go
index 561d8d6..c2af951 100644
--- a/cc/config/mips64_device.go
+++ b/cc/config/mips64_device.go
@@ -55,15 +55,6 @@
 )
 
 func init() {
-	android.RegisterArchVariants(android.Mips64,
-		"mips64r2",
-		"mips64r6")
-	android.RegisterArchFeatures(android.Mips64,
-		"rev6",
-		"msa")
-	android.RegisterArchVariantFeatures(android.Mips64, "mips64r6",
-		"rev6")
-
 	pctx.StaticVariable("mips64GccVersion", mips64GccVersion)
 
 	pctx.SourcePathVariable("Mips64GccRoot",
diff --git a/cc/config/mips_device.go b/cc/config/mips_device.go
index 8cd35b3..ddbc41b 100644
--- a/cc/config/mips_device.go
+++ b/cc/config/mips_device.go
@@ -89,22 +89,6 @@
 )
 
 func init() {
-	android.RegisterArchVariants(android.Mips,
-		"mips32_fp",
-		"mips32r2_fp",
-		"mips32r2_fp_xburst",
-		"mips32r2dsp_fp",
-		"mips32r2dspr2_fp",
-		"mips32r6")
-	android.RegisterArchFeatures(android.Mips,
-		"dspr2",
-		"rev6",
-		"msa")
-	android.RegisterArchVariantFeatures(android.Mips, "mips32r2dspr2_fp",
-		"dspr2")
-	android.RegisterArchVariantFeatures(android.Mips, "mips32r6",
-		"rev6")
-
 	pctx.StaticVariable("mipsGccVersion", mipsGccVersion)
 
 	pctx.SourcePathVariable("MipsGccRoot",
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index 381f7e7..4264eda 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -68,54 +68,12 @@
 )
 
 func init() {
-	android.RegisterArchVariants(android.X86_64,
-		"haswell",
-		"ivybridge",
-		"sandybridge",
-		"silvermont")
-	android.RegisterArchFeatures(android.X86_64,
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"avx",
-		"popcnt")
 	android.RegisterDefaultArchVariantFeatures(android.Android, android.X86_64,
 		"ssse3",
 		"sse4",
 		"sse4_1",
 		"sse4_2",
 		"popcnt")
-	android.RegisterArchVariantFeatures(android.X86_64, "haswell",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"avx",
-		"popcnt")
-	android.RegisterArchVariantFeatures(android.X86_64, "ivybridge",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"avx",
-		"popcnt")
-	android.RegisterArchVariantFeatures(android.X86_64, "sandybridge",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"popcnt")
-	android.RegisterArchVariantFeatures(android.X86_64, "silvermont",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"popcnt")
 
 	pctx.StaticVariable("x86_64GccVersion", x86_64GccVersion)
 
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index fc0b1d8..34e7df8 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -84,63 +84,6 @@
 )
 
 func init() {
-	android.RegisterArchVariants(android.X86,
-		"atom",
-		"haswell",
-		"ivybridge",
-		"sandybridge",
-		"silvermont",
-		"x86_64")
-	android.RegisterArchFeatures(android.X86,
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"avx",
-		"popcnt",
-		"movbe")
-	android.RegisterArchVariantFeatures(android.X86, "x86_64",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"popcnt")
-	android.RegisterArchVariantFeatures(android.X86, "atom",
-		"ssse3",
-		"movbe")
-	android.RegisterArchVariantFeatures(android.X86, "haswell",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"avx",
-		"popcnt",
-		"movbe")
-	android.RegisterArchVariantFeatures(android.X86, "ivybridge",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"avx",
-		"popcnt")
-	android.RegisterArchVariantFeatures(android.X86, "sandybridge",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"popcnt")
-	android.RegisterArchVariantFeatures(android.X86, "silvermont",
-		"ssse3",
-		"sse4",
-		"sse4_1",
-		"sse4_2",
-		"aes_ni",
-		"popcnt",
-		"movbe")
-
 	pctx.StaticVariable("x86GccVersion", x86GccVersion)
 
 	pctx.SourcePathVariable("X86GccRoot",
diff --git a/java/androidmk.go b/java/androidmk.go
index 4d3af12..7b81273 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -22,6 +22,25 @@
 	"android/soong/android"
 )
 
+func (library *Library) AndroidMkHostDex(w io.Writer, name string, data android.AndroidMkData) {
+	if Bool(library.deviceProperties.Hostdex) && !library.Host() {
+		fmt.Fprintln(w, "include $(CLEAR_VARS)")
+		fmt.Fprintln(w, "LOCAL_MODULE := "+name+"-hostdex")
+		fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
+		fmt.Fprintln(w, "LOCAL_MODULE_CLASS := JAVA_LIBRARIES")
+		if library.installFile == nil {
+			fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+		}
+		if library.dexJarFile != nil {
+			fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", library.dexJarFile.String())
+		}
+		fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.headerJarFile.String())
+		fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", library.implementationAndResourcesJar.String())
+		fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(data.Required, " "))
+		fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
+	}
+}
+
 func (library *Library) AndroidMk() android.AndroidMkData {
 	return android.AndroidMkData{
 		Class:      "JAVA_LIBRARIES",
@@ -69,23 +88,7 @@
 		},
 		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
 			android.WriteAndroidMkData(w, data)
-
-			if Bool(library.deviceProperties.Hostdex) && !library.Host() {
-				fmt.Fprintln(w, "include $(CLEAR_VARS)")
-				fmt.Fprintln(w, "LOCAL_MODULE := "+name+"-hostdex")
-				fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
-				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := JAVA_LIBRARIES")
-				if library.installFile == nil {
-					fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
-				}
-				if library.dexJarFile != nil {
-					fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", library.dexJarFile.String())
-				}
-				fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", library.headerJarFile.String())
-				fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", library.implementationAndResourcesJar.String())
-				fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+strings.Join(data.Required, " "))
-				fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
-			}
+			library.AndroidMkHostDex(w, name, data)
 		},
 	}
 }
diff --git a/java/droiddoc.go b/java/droiddoc.go
index bd3b3ab..055eb07 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -629,14 +629,7 @@
 			case Dependency:
 				deps.classpath = append(deps.classpath, dep.HeaderJars()...)
 			case SdkLibraryDependency:
-				sdkVersion := j.sdkVersion()
-				linkType := javaSdk
-				if strings.HasPrefix(sdkVersion, "system_") || strings.HasPrefix(sdkVersion, "test_") {
-					linkType = javaSystem
-				} else if sdkVersion == "" {
-					linkType = javaPlatform
-				}
-				deps.classpath = append(deps.classpath, dep.ImplementationJars(linkType)...)
+				deps.classpath = append(deps.classpath, dep.ImplementationJars(ctx, j.sdkVersion())...)
 			case android.SourceFileProducer:
 				checkProducesJars(ctx, dep)
 				deps.classpath = append(deps.classpath, dep.Srcs()...)
diff --git a/java/java.go b/java/java.go
index a23835b..2ac5a5b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -336,8 +336,8 @@
 }
 
 type SdkLibraryDependency interface {
-	HeaderJars(linkType linkType) android.Paths
-	ImplementationJars(linkType linkType) android.Paths
+	HeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths
+	ImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths
 }
 
 type SrcDependency interface {
@@ -729,8 +729,7 @@
 		case SdkLibraryDependency:
 			switch tag {
 			case libTag:
-				linkType, _ := getLinkType(j, ctx.ModuleName())
-				deps.classpath = append(deps.classpath, dep.HeaderJars(linkType)...)
+				deps.classpath = append(deps.classpath, dep.HeaderJars(ctx, j.sdkVersion())...)
 				// names of sdk libs that are directly depended are exported
 				j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
 			default:
@@ -748,6 +747,8 @@
 				deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
 			case android.DefaultsDepTag, android.SourceDepTag:
 				// Nothing to do
+			case publicApiFileTag, systemApiFileTag, testApiFileTag:
+				// Nothing to do
 			default:
 				ctx.ModuleErrorf("dependency on genrule %q may only be in srcs, libs, or static_libs", otherName)
 			}
@@ -997,12 +998,11 @@
 	if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") {
 		if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
 			enable_sharding = true
-			if len(j.properties.Annotation_processors) != 0 ||
-				len(j.properties.Annotation_processor_classes) != 0 {
-				ctx.PropertyErrorf("javac_shard_size",
-					"%q cannot be set when annotation processors are enabled.",
-					j.properties.Javac_shard_size)
-			}
+			// Formerly, there was a check here that prevented annotation processors
+			// from being used when sharding was enabled, as some annotation processors
+			// do not function correctly in sharded environments. It was removed to
+			// allow for the use of annotation processors that do function correctly
+			// with sharding enabled. See: b/77284273.
 		}
 		j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
 		if ctx.Failed() {
diff --git a/java/java_test.go b/java/java_test.go
index 570efb7..7a37b7b 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -861,7 +861,6 @@
 	ctx.ModuleForTests("foo"+sdkDocsSuffix, "android_common")
 	ctx.ModuleForTests("foo"+sdkDocsSuffix+sdkSystemApiSuffix, "android_common")
 	ctx.ModuleForTests("foo"+sdkDocsSuffix+sdkTestApiSuffix, "android_common")
-	ctx.ModuleForTests("foo"+sdkImplLibrarySuffix, "android_common")
 	ctx.ModuleForTests("foo"+sdkXmlFileSuffix, "android_common")
 	ctx.ModuleForTests("foo.api.public.28", "")
 	ctx.ModuleForTests("foo.api.system.28", "")
@@ -874,9 +873,9 @@
 			"foo.stubs.system.jar")
 	}
 	// ... and not to the impl lib
-	if strings.Contains(bazJavac.Args["classpath"], "foo.impl.jar") {
+	if strings.Contains(bazJavac.Args["classpath"], "foo.jar") {
 		t.Errorf("baz javac classpath %v should not contain %q", bazJavac.Args["classpath"],
-			"foo.impl.jar")
+			"foo.jar")
 	}
 	// test if baz is not linked to the system variant of foo
 	if strings.Contains(bazJavac.Args["classpath"], "foo.stubs.jar") {
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 59b2092..c11e010 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -17,7 +17,6 @@
 import (
 	"android/soong/android"
 	"sort"
-	"strconv"
 	"strings"
 
 	"github.com/google/blueprint/proptools"
@@ -66,14 +65,9 @@
 	return
 }
 
-func parseApiFilePath(ctx android.BaseModuleContext, path string) (module string, apiver int, scope string) {
+func parseApiFilePath(ctx android.BaseModuleContext, path string) (module string, apiver string, scope string) {
 	elements := strings.Split(path, "/")
-	ver, err := strconv.Atoi(elements[0])
-	if err != nil {
-		ctx.ModuleErrorf("invalid version %q found in path: %q", elements[0], path)
-		return
-	}
-	apiver = ver
+	apiver = elements[0]
 
 	scope = elements[1]
 	if scope != "public" && scope != "system" && scope != "test" {
@@ -151,7 +145,7 @@
 	type latestApiInfo struct {
 		module string
 		scope  string
-		apiver int
+		apiver string
 		path   string
 	}
 	m := make(map[string]latestApiInfo)
@@ -160,14 +154,15 @@
 		// create a filegroup for each api txt file
 		localPath := strings.TrimPrefix(f, mydir)
 		module, apiver, scope := parseApiFilePath(mctx, localPath)
-		createFilegroup(mctx, module, scope, strconv.Itoa(apiver), localPath)
+		createFilegroup(mctx, module, scope, apiver, localPath)
 
 		// find the latest apiver
 		key := module + "." + scope
 		info, ok := m[key]
 		if !ok {
 			m[key] = latestApiInfo{module, scope, apiver, localPath}
-		} else if apiver > info.apiver {
+		} else if len(apiver) > len(info.apiver) || (len(apiver) == len(info.apiver) &&
+			strings.Compare(apiver, info.apiver) > 0) {
 			info.apiver = apiver
 			info.path = localPath
 		}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 941e665..d33149b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -20,6 +20,7 @@
 	"fmt"
 	"io"
 	"path"
+	"path/filepath"
 	"sort"
 	"strings"
 	"sync"
@@ -33,7 +34,6 @@
 	sdkSystemApiSuffix    = ".system"
 	sdkTestApiSuffix      = ".test"
 	sdkDocsSuffix         = ".docs"
-	sdkImplLibrarySuffix  = ".impl"
 	sdkXmlFileSuffix      = ".xml"
 )
 
@@ -46,7 +46,6 @@
 	publicApiStubsTag = dependencyTag{name: "public"}
 	systemApiStubsTag = dependencyTag{name: "system"}
 	testApiStubsTag   = dependencyTag{name: "test"}
-	implLibTag        = dependencyTag{name: "platform"}
 	publicApiFileTag  = dependencyTag{name: "publicApi"}
 	systemApiFileTag  = dependencyTag{name: "systemApi"}
 	testApiFileTag    = dependencyTag{name: "testApi"}
@@ -89,20 +88,9 @@
 }
 
 type sdkLibraryProperties struct {
-	// list of source files used to compile the Java module.  May be .java, .logtags, .proto,
-	// or .aidl files.
-	Srcs []string `android:"arch_variant"`
-
 	// list of optional source files that are part of API but not part of runtime library.
 	Api_srcs []string `android:"arch_variant"`
 
-	// list of of java libraries that will be in the classpath
-	Libs []string `android:"arch_variant"`
-
-	// list of java libraries that will be compiled into the resulting runtime jar.
-	// These libraries are not compiled into the stubs jar.
-	Static_libs []string `android:"arch_variant"`
-
 	// List of Java libraries that will be in the classpath when building stubs
 	Stub_only_libs []string `android:"arch_variant"`
 
@@ -112,18 +100,9 @@
 	// list of package names that must be hidden from the API
 	Hidden_api_packages []string
 
-	Errorprone struct {
-		// List of javac flags that should only be used when running errorprone.
-		Javacflags []string
-	}
-
 	// Additional droiddoc options
 	Droiddoc_options []string
 
-	// If set to true, compile dex regardless of installable.  Defaults to false.
-	// This applies to the stubs lib.
-	Compile_dex *bool
-
 	// the java library (in classpath) for documentation that provides java srcs and srcjars.
 	Srcs_lib *string
 
@@ -134,27 +113,32 @@
 	// Defaults to "android.annotation".
 	Srcs_lib_whitelist_pkgs []string
 
+	// a list of top-level directories containing files to merge qualifier annotations
+	// (i.e. those intended to be included in the stubs written) from.
+	Merge_annotations_dirs []string
+
+	// a list of top-level directories containing Java stub files to merge show/hide annotations from.
+	Merge_inclusion_annotations_dirs []string
+
+	// If set to true, the path of dist files is apistubs/core. Defaults to false.
+	Core_lib *bool
+
 	// TODO: determines whether to create HTML doc or not
 	//Html_doc *bool
 }
 
 type sdkLibrary struct {
-	android.ModuleBase
-	android.DefaultableModuleBase
+	Library
 
-	properties          sdkLibraryProperties
-	deviceProperties    CompilerDeviceProperties
-	dexpreoptProperties DexpreoptProperties
+	sdkLibraryProperties sdkLibraryProperties
 
 	publicApiStubsPath android.Paths
 	systemApiStubsPath android.Paths
 	testApiStubsPath   android.Paths
-	implLibPath        android.Paths
 
 	publicApiStubsImplPath android.Paths
 	systemApiStubsImplPath android.Paths
 	testApiStubsImplPath   android.Paths
-	implLibImplPath        android.Paths
 
 	publicApiFilePath android.Path
 	systemApiFilePath android.Path
@@ -164,16 +148,21 @@
 func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
 	// Add dependencies to the stubs library
 	ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
-	ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
-	ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
-	ctx.AddVariationDependencies(nil, implLibTag, module.implName())
-
 	ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
-	ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
-	ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
+
+	if !Bool(module.properties.No_standard_libs) {
+		ctx.AddVariationDependencies(nil, systemApiStubsTag, module.stubsName(apiScopeSystem))
+		ctx.AddVariationDependencies(nil, systemApiFileTag, module.docsName(apiScopeSystem))
+		ctx.AddVariationDependencies(nil, testApiFileTag, module.docsName(apiScopeTest))
+		ctx.AddVariationDependencies(nil, testApiStubsTag, module.stubsName(apiScopeTest))
+	}
+
+	module.Library.deps(ctx)
 }
 
 func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+	module.Library.GenerateAndroidBuildActions(ctx)
+
 	// Record the paths to the header jars of the library (stubs and impl).
 	// When this java_sdk_library is dependened from others via "libs" property,
 	// the recorded paths will be returned depending on the link type of the caller.
@@ -192,11 +181,6 @@
 			case testApiStubsTag:
 				module.testApiStubsPath = lib.HeaderJars()
 				module.testApiStubsImplPath = lib.ImplementationJars()
-			case implLibTag:
-				module.implLibPath = lib.HeaderJars()
-				module.implLibImplPath = lib.ImplementationJars()
-			default:
-				ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
 			}
 		}
 		if doc, ok := to.(ApiFilePath); ok {
@@ -215,58 +199,62 @@
 }
 
 func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
-	return android.AndroidMkData{
-		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
-			// Create a phony module that installs the impl library, for the case when this lib is
-			// in PRODUCT_PACKAGES.
-			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
-			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
-			fmt.Fprintln(w, "LOCAL_MODULE :=", name)
-			fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES := "+module.implName())
-			fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
-			owner := module.ModuleBase.Owner()
-			if owner == "" {
+	data := module.Library.AndroidMk()
+	data.Required = append(data.Required, module.xmlFileName())
+
+	data.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+		android.WriteAndroidMkData(w, data)
+
+		module.Library.AndroidMkHostDex(w, name, data)
+		// Create a phony module that installs the impl library, for the case when this lib is
+		// in PRODUCT_PACKAGES.
+		owner := module.ModuleBase.Owner()
+		if owner == "" {
+			if Bool(module.sdkLibraryProperties.Core_lib) {
+				owner = "core"
+			} else {
 				owner = "android"
 			}
-			// Create dist rules to install the stubs libs to the dist dir
-			if len(module.publicApiStubsPath) == 1 {
-				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.publicApiStubsImplPath.Strings()[0]+
-					":"+path.Join("apistubs", owner, "public",
-					module.BaseModuleName()+".jar")+")")
-			}
-			if len(module.systemApiStubsPath) == 1 {
-				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.systemApiStubsImplPath.Strings()[0]+
-					":"+path.Join("apistubs", owner, "system",
-					module.BaseModuleName()+".jar")+")")
-			}
-			if len(module.testApiStubsPath) == 1 {
-				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.testApiStubsImplPath.Strings()[0]+
-					":"+path.Join("apistubs", owner, "test",
-					module.BaseModuleName()+".jar")+")")
-			}
-			if module.publicApiFilePath != nil {
-				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.publicApiFilePath.String()+
-					":"+path.Join("apistubs", owner, "public", "api",
-					module.BaseModuleName()+".txt")+")")
-			}
-			if module.systemApiFilePath != nil {
-				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.systemApiFilePath.String()+
-					":"+path.Join("apistubs", owner, "system", "api",
-					module.BaseModuleName()+".txt")+")")
-			}
-			if module.testApiFilePath != nil {
-				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.testApiFilePath.String()+
-					":"+path.Join("apistubs", owner, "test", "api",
-					module.BaseModuleName()+".txt")+")")
-			}
-		},
+		}
+		// Create dist rules to install the stubs libs to the dist dir
+		if len(module.publicApiStubsPath) == 1 {
+			fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+				module.publicApiStubsImplPath.Strings()[0]+
+				":"+path.Join("apistubs", owner, "public",
+				module.BaseModuleName()+".jar")+")")
+		}
+		if len(module.systemApiStubsPath) == 1 {
+			fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+				module.systemApiStubsImplPath.Strings()[0]+
+				":"+path.Join("apistubs", owner, "system",
+				module.BaseModuleName()+".jar")+")")
+		}
+		if len(module.testApiStubsPath) == 1 {
+			fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+				module.testApiStubsImplPath.Strings()[0]+
+				":"+path.Join("apistubs", owner, "test",
+				module.BaseModuleName()+".jar")+")")
+		}
+		if module.publicApiFilePath != nil {
+			fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+				module.publicApiFilePath.String()+
+				":"+path.Join("apistubs", owner, "public", "api",
+				module.BaseModuleName()+".txt")+")")
+		}
+		if module.systemApiFilePath != nil {
+			fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+				module.systemApiFilePath.String()+
+				":"+path.Join("apistubs", owner, "system", "api",
+				module.BaseModuleName()+".txt")+")")
+		}
+		if module.testApiFilePath != nil {
+			fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
+				module.testApiFilePath.String()+
+				":"+path.Join("apistubs", owner, "test", "api",
+				module.BaseModuleName()+".txt")+")")
+		}
 	}
+	return data
 }
 
 // Module name of the stubs library
@@ -295,7 +283,7 @@
 
 // Module name of the runtime implementation library
 func (module *sdkLibrary) implName() string {
-	return module.BaseModuleName() + sdkImplLibrarySuffix
+	return module.BaseModuleName()
 }
 
 // File path to the runtime implementation library
@@ -385,6 +373,9 @@
 		Device_specific   *bool
 		Product_specific  *bool
 		Compile_dex       *bool
+		No_standard_libs  *bool
+		System_modules    *string
+		Java_version      *string
 		Product_variables struct {
 			Unbundled_build struct {
 				Enabled *bool
@@ -393,18 +384,27 @@
 				Enabled *bool
 			}
 		}
+		Openjdk9 struct {
+			Srcs       []string
+			Javacflags []string
+		}
 	}{}
 
 	props.Name = proptools.StringPtr(module.stubsName(apiScope))
 	// sources are generated from the droiddoc
 	props.Srcs = []string{":" + module.docsName(apiScope)}
 	props.Sdk_version = proptools.StringPtr(module.sdkVersion(apiScope))
-	props.Libs = module.properties.Stub_only_libs
+	props.Libs = module.sdkLibraryProperties.Stub_only_libs
 	// Unbundled apps will use the prebult one from /prebuilts/sdk
 	props.Product_variables.Unbundled_build.Enabled = proptools.BoolPtr(false)
 	props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
-	if module.properties.Compile_dex != nil {
-		props.Compile_dex = module.properties.Compile_dex
+	props.No_standard_libs = module.Library.Module.properties.No_standard_libs
+	props.System_modules = module.Library.Module.deviceProperties.System_modules
+	props.Openjdk9.Srcs = module.Library.Module.properties.Openjdk9.Srcs
+	props.Openjdk9.Javacflags = module.Library.Module.properties.Openjdk9.Javacflags
+	props.Java_version = module.Library.Module.properties.Java_version
+	if module.Library.Module.deviceProperties.Compile_dex != nil {
+		props.Compile_dex = module.Library.Module.deviceProperties.Compile_dex
 	}
 
 	if module.SocSpecific() {
@@ -422,18 +422,22 @@
 // files
 func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
 	props := struct {
-		Name                    *string
-		Srcs                    []string
-		Installable             *bool
-		Srcs_lib                *string
-		Srcs_lib_whitelist_dirs []string
-		Srcs_lib_whitelist_pkgs []string
-		Libs                    []string
-		Args                    *string
-		Api_tag_name            *string
-		Api_filename            *string
-		Removed_api_filename    *string
-		Check_api               struct {
+		Name                             *string
+		Srcs                             []string
+		Installable                      *bool
+		Srcs_lib                         *string
+		Srcs_lib_whitelist_dirs          []string
+		Srcs_lib_whitelist_pkgs          []string
+		Libs                             []string
+		Args                             *string
+		Api_tag_name                     *string
+		Api_filename                     *string
+		Removed_api_filename             *string
+		No_standard_libs                 *bool
+		Java_version                     *string
+		Merge_annotations_dirs           []string
+		Merge_inclusion_annotations_dirs []string
+		Check_api                        struct {
 			Current       ApiToCheck
 			Last_released ApiToCheck
 		}
@@ -444,19 +448,24 @@
 	}{}
 
 	props.Name = proptools.StringPtr(module.docsName(apiScope))
-	props.Srcs = append(props.Srcs, module.properties.Srcs...)
-	props.Srcs = append(props.Srcs, module.properties.Api_srcs...)
+	props.Srcs = append(props.Srcs, module.Library.Module.properties.Srcs...)
+	props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
 	props.Installable = proptools.BoolPtr(false)
 	// A droiddoc module has only one Libs property and doesn't distinguish between
 	// shared libs and static libs. So we need to add both of these libs to Libs property.
-	props.Libs = module.properties.Libs
-	props.Libs = append(props.Libs, module.properties.Static_libs...)
-	props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
-	props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
+	props.Libs = module.Library.Module.properties.Libs
+	props.Libs = append(props.Libs, module.Library.Module.properties.Static_libs...)
+	props.Aidl.Include_dirs = module.Library.Module.deviceProperties.Aidl.Include_dirs
+	props.Aidl.Local_include_dirs = module.Library.Module.deviceProperties.Aidl.Local_include_dirs
+	props.No_standard_libs = module.Library.Module.properties.No_standard_libs
+	props.Java_version = module.Library.Module.properties.Java_version
 
-	droiddocArgs := " --stub-packages " + strings.Join(module.properties.Api_packages, ":") +
-		" " + android.JoinWithPrefix(module.properties.Hidden_api_packages, " --hide-package ") +
-		" " + android.JoinWithPrefix(module.properties.Droiddoc_options, " ") +
+	props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
+	props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
+
+	droiddocArgs := " --stub-packages " + strings.Join(module.sdkLibraryProperties.Api_packages, ":") +
+		" " + android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package ") +
+		" " + android.JoinWithPrefix(module.sdkLibraryProperties.Droiddoc_options, " ") +
 		" --hide MissingPermission --hide BroadcastBehavior " +
 		"--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
 		"--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
@@ -498,55 +507,13 @@
 		module.latestApiFilegroupName(apiScope))
 	props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
 		module.latestRemovedApiFilegroupName(apiScope))
-	props.Srcs_lib = module.properties.Srcs_lib
-	props.Srcs_lib_whitelist_dirs = module.properties.Srcs_lib_whitelist_dirs
-	props.Srcs_lib_whitelist_pkgs = module.properties.Srcs_lib_whitelist_pkgs
+	props.Srcs_lib = module.sdkLibraryProperties.Srcs_lib
+	props.Srcs_lib_whitelist_dirs = module.sdkLibraryProperties.Srcs_lib_whitelist_dirs
+	props.Srcs_lib_whitelist_pkgs = module.sdkLibraryProperties.Srcs_lib_whitelist_pkgs
 
 	mctx.CreateModule(android.ModuleFactoryAdaptor(DroidstubsFactory), &props)
 }
 
-// Creates the runtime library. This is not directly linkable from other modules.
-func (module *sdkLibrary) createImplLibrary(mctx android.TopDownMutatorContext) {
-	props := struct {
-		Name             *string
-		Srcs             []string
-		Libs             []string
-		Static_libs      []string
-		Soc_specific     *bool
-		Device_specific  *bool
-		Product_specific *bool
-		Installable      *bool
-		Required         []string
-		Errorprone       struct {
-			Javacflags []string
-		}
-		IsSDKLibrary bool
-	}{}
-
-	props.Name = proptools.StringPtr(module.implName())
-	props.Srcs = module.properties.Srcs
-	props.Libs = module.properties.Libs
-	props.Static_libs = module.properties.Static_libs
-	props.Installable = proptools.BoolPtr(true)
-	// XML file is installed along with the impl lib
-	props.Required = []string{module.xmlFileName()}
-	props.Errorprone.Javacflags = module.properties.Errorprone.Javacflags
-	props.IsSDKLibrary = true
-
-	if module.SocSpecific() {
-		props.Soc_specific = proptools.BoolPtr(true)
-	} else if module.DeviceSpecific() {
-		props.Device_specific = proptools.BoolPtr(true)
-	} else if module.ProductSpecific() {
-		props.Product_specific = proptools.BoolPtr(true)
-	}
-
-	mctx.CreateModule(android.ModuleFactoryAdaptor(LibraryFactory),
-		&props,
-		&module.deviceProperties,
-		&module.dexpreoptProperties)
-}
-
 // Creates the xml file that publicizes the runtime library
 func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
 	template := `
@@ -607,27 +574,54 @@
 	mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
 }
 
-// to satisfy SdkLibraryDependency interface
-func (module *sdkLibrary) HeaderJars(linkType linkType) android.Paths {
-	// This module is just a wrapper for the stubs.
-	if linkType == javaSystem {
-		return module.systemApiStubsPath
-	} else if linkType == javaPlatform {
-		return module.implLibPath
+func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
+	var api, v string
+	if sdkVersion == "" {
+		api = "system"
+		v = "current"
+	} else if strings.Contains(sdkVersion, "_") {
+		t := strings.Split(sdkVersion, "_")
+		api = t[0]
+		v = t[1]
 	} else {
-		return module.publicApiStubsPath
+		api = "public"
+		v = sdkVersion
+	}
+	dir := filepath.Join("prebuilts", "sdk", v, api)
+	jar := filepath.Join(dir, module.BaseModuleName()+".jar")
+	jarPath := android.ExistentPathForSource(ctx, jar)
+	return android.Paths{jarPath.Path()}
+}
+
+// to satisfy SdkLibraryDependency interface
+func (module *sdkLibrary) HeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
+	// This module is just a wrapper for the stubs.
+	if ctx.Config().UnbundledBuild() {
+		return module.PrebuiltJars(ctx, sdkVersion)
+	} else {
+		if strings.HasPrefix(sdkVersion, "system_") {
+			return module.systemApiStubsPath
+		} else if sdkVersion == "" {
+			return module.Library.HeaderJars()
+		} else {
+			return module.publicApiStubsPath
+		}
 	}
 }
 
 // to satisfy SdkLibraryDependency interface
-func (module *sdkLibrary) ImplementationJars(linkType linkType) android.Paths {
+func (module *sdkLibrary) ImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
 	// This module is just a wrapper for the stubs.
-	if linkType == javaSystem {
-		return module.systemApiStubsImplPath
-	} else if linkType == javaPlatform {
-		return module.implLibImplPath
+	if ctx.Config().UnbundledBuild() {
+		return module.PrebuiltJars(ctx, sdkVersion)
 	} else {
-		return module.publicApiStubsImplPath
+		if strings.HasPrefix(sdkVersion, "system_") {
+			return module.systemApiStubsImplPath
+		} else if sdkVersion == "" {
+			return module.Library.ImplementationJars()
+		} else {
+			return module.publicApiStubsImplPath
+		}
 	}
 }
 
@@ -642,28 +636,29 @@
 // once for public API level and once for system API level
 func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
 	if module, ok := mctx.Module().(*sdkLibrary); ok {
-		if module.properties.Srcs == nil {
+		if module.Library.Module.properties.Srcs == nil {
 			mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
 		}
-		if module.properties.Api_packages == nil {
+
+		if module.sdkLibraryProperties.Api_packages == nil {
 			mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
 		}
-
 		// for public API stubs
 		module.createStubsLibrary(mctx, apiScopePublic)
 		module.createDocs(mctx, apiScopePublic)
 
-		// for system API stubs
-		module.createStubsLibrary(mctx, apiScopeSystem)
-		module.createDocs(mctx, apiScopeSystem)
+		if !Bool(module.properties.No_standard_libs) {
+			// for system API stubs
+			module.createStubsLibrary(mctx, apiScopeSystem)
+			module.createDocs(mctx, apiScopeSystem)
 
-		// for test API stubs
-		module.createStubsLibrary(mctx, apiScopeTest)
-		module.createDocs(mctx, apiScopeTest)
+			// for test API stubs
+			module.createStubsLibrary(mctx, apiScopeTest)
+			module.createDocs(mctx, apiScopeTest)
 
-		// for runtime
-		module.createXmlFile(mctx)
-		module.createImplLibrary(mctx)
+			// for runtime
+			module.createXmlFile(mctx)
+		}
 
 		// record java_sdk_library modules so that they are exported to make
 		javaSdkLibraries := javaSdkLibraries(mctx.Config())
@@ -675,9 +670,17 @@
 
 func sdkLibraryFactory() android.Module {
 	module := &sdkLibrary{}
-	module.AddProperties(&module.properties)
-	module.AddProperties(&module.deviceProperties)
-	module.AddProperties(&module.dexpreoptProperties)
-	InitJavaModule(module, android.DeviceSupported)
+	module.AddProperties(
+		&module.sdkLibraryProperties,
+		&module.Library.Module.properties,
+		&module.Library.Module.dexpreoptProperties,
+		&module.Library.Module.deviceProperties,
+		&module.Library.Module.protoProperties,
+	)
+
+	module.Library.Module.properties.Installable = proptools.BoolPtr(true)
+	module.Library.Module.deviceProperties.IsSDKLibrary = true
+
+	InitJavaModule(module, android.HostAndDeviceSupported)
 	return module
 }
diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go
index f77eebb..85c4a9a 100644
--- a/ui/build/sandbox_linux.go
+++ b/ui/build/sandbox_linux.go
@@ -127,6 +127,9 @@
 		// in soong_ui
 		"-e",
 
+		// Mount /proc read-write, necessary to run a nested nsjail or minijail0
+		"--proc_rw",
+
 		// Use a consistent user & group.
 		// Note that these are mapped back to the real UID/GID when
 		// doing filesystem operations, so they're rather arbitrary.