Merge "Remove unused variable SKIP_BOOT_JARS_CHECK."
diff --git a/android/arch.go b/android/arch.go
index 6add1b1..273c02b 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1999,12 +1999,7 @@
 		// Create a new instance of the requested property set
 		value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
 
-		// Merge all the structs together
-		for _, propertyStruct := range propertyStructs {
-			mergePropertyStruct(ctx, value, propertyStruct)
-		}
-
-		archToProp[arch.Name] = value
+		archToProp[arch.Name] = mergeStructs(ctx, propertyStructs, value)
 	}
 	axisToProps[bazel.ArchConfigurationAxis] = archToProp
 
@@ -2016,19 +2011,50 @@
 			// It looks like this OS value is not used in Blueprint files
 			continue
 		}
-		osToProp[os.Name] = getTargetStruct(ctx, propertySet, archProperties, os.Field)
+		osStructs, ok := getTargetStructs(ctx, archProperties, os.Field)
+		if ok {
+			osToProp[os.Name] = mergeStructs(ctx, osStructs, propertySet)
+		}
+
 		// For arm, x86, ...
 		for _, arch := range osArchTypeMap[os] {
+			osArchStructs := make([]reflect.Value, 0)
+
 			targetField := GetCompoundTargetField(os, arch)
 			targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name)
-			archOsToProp[targetName] = getTargetStruct(ctx, propertySet, archProperties, targetField)
+			targetStructs, ok := getTargetStructs(ctx, archProperties, targetField)
+			if ok {
+				osArchStructs = append(osArchStructs, targetStructs...)
+			}
+
+			// Auto-combine with Linux_ and Bionic_ targets. This potentially results in
+			// repetition and select() bloat, but use of Linux_* and Bionic_* targets is rare.
+			// TODO(b/201423152): Look into cleanup.
+			if os.Linux() {
+				targetField := "Linux_" + arch.Name
+				targetStructs, ok := getTargetStructs(ctx, archProperties, targetField)
+				if ok {
+					osArchStructs = append(osArchStructs, targetStructs...)
+				}
+			}
+			if os.Bionic() {
+				targetField := "Bionic_" + arch.Name
+				targetStructs, ok := getTargetStructs(ctx, archProperties, targetField)
+				if ok {
+					osArchStructs = append(osArchStructs, targetStructs...)
+				}
+			}
+
+			archOsToProp[targetName] = mergeStructs(ctx, osArchStructs, propertySet)
 		}
 	}
 	axisToProps[bazel.OsConfigurationAxis] = osToProp
 	axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp
 
-	axisToProps[bazel.BionicConfigurationAxis] = map[string]interface{}{
-		"bionic": getTargetStruct(ctx, propertySet, archProperties, "Bionic"),
+	bionicStructs, ok := getTargetStructs(ctx, archProperties, "Bionic")
+	if ok {
+		axisToProps[bazel.BionicConfigurationAxis] = map[string]interface{}{
+			"bionic": mergeStructs(ctx, bionicStructs, propertySet)}
 	}
 
 	return axisToProps
@@ -2048,7 +2074,7 @@
 //      }
 //    }
 // This would return a BaseCompilerProperties with BaseCompilerProperties.Srcs = ["foo.c"]
-func getTargetStruct(ctx ArchVariantContext, propertySet interface{}, archProperties []interface{}, targetName string) interface{} {
+func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targetName string) ([]reflect.Value, bool) {
 	propertyStructs := make([]reflect.Value, 0)
 	for _, archProperty := range archProperties {
 		archPropValues := reflect.ValueOf(archProperty).Elem()
@@ -2056,9 +2082,15 @@
 		targetStruct, ok := getChildPropertyStruct(ctx, targetProp, targetName, targetName)
 		if ok {
 			propertyStructs = append(propertyStructs, targetStruct)
+		} else {
+			return propertyStructs, false
 		}
 	}
 
+	return propertyStructs, true
+}
+
+func mergeStructs(ctx ArchVariantContext, propertyStructs []reflect.Value, propertySet interface{}) interface{} {
 	// Create a new instance of the requested property set
 	value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
 
diff --git a/android/bazel.go b/android/bazel.go
index 962a8f0e..53e6060 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -162,36 +162,56 @@
 		"external/jsr305":/* recursive = */ true,
 		"frameworks/ex/common":/* recursive = */ true,
 
-		"prebuilts/sdk":/* recursive = */ false,
-		"prebuilts/sdk/tools":/* recursive = */ false,
-		"prebuilts/r8":/* recursive = */ false,
 		"packages/apps/Music":/* recursive = */ true,
 		"packages/apps/QuickSearchBox":/* recursive = */ true,
+		"packages/apps/WallpaperPicker":/* recursive = */ false,
+
+		"prebuilts/sdk":/* recursive = */ false,
+		"prebuilts/sdk/current/extras/app-toolkit":/* recursive = */ false,
+		"prebuilts/sdk/current/support":/* recursive = */ false,
+		"prebuilts/sdk/tools":/* recursive = */ false,
+		"prebuilts/r8":/* recursive = */ false,
 	}
 
 	// Configure modules in these directories to enable bp2build_available: true or false by default.
 	bp2buildDefaultConfig = Bp2BuildConfig{
-		"bionic":                            Bp2BuildDefaultTrueRecursively,
-		"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
-		"development/sdk":                   Bp2BuildDefaultTrueRecursively,
-		"external/gwp_asan":                 Bp2BuildDefaultTrueRecursively,
-		"external/brotli":                   Bp2BuildDefaultTrue,
-		"system/core/libcutils":             Bp2BuildDefaultTrueRecursively,
-		"system/core/libprocessgroup":       Bp2BuildDefaultTrue,
+		"bionic":                                             Bp2BuildDefaultTrueRecursively,
+		"build/bazel/examples/apex/minimal":                  Bp2BuildDefaultTrueRecursively,
+		"development/sdk":                                    Bp2BuildDefaultTrueRecursively,
+		"external/arm-optimized-routines":                    Bp2BuildDefaultTrueRecursively,
+		"external/boringssl":                                 Bp2BuildDefaultTrueRecursively,
+		"external/brotli":                                    Bp2BuildDefaultTrue,
+		"external/fmtlib":                                    Bp2BuildDefaultTrueRecursively,
+		"external/gwp_asan":                                  Bp2BuildDefaultTrueRecursively,
+		"external/jemalloc_new":                              Bp2BuildDefaultTrueRecursively,
+		"external/libcap":                                    Bp2BuildDefaultTrueRecursively,
+		"external/libcxx":                                    Bp2BuildDefaultTrueRecursively,
+		"external/libcxxabi":                                 Bp2BuildDefaultTrueRecursively,
+		"external/lz4/lib":                                   Bp2BuildDefaultTrue,
+		"external/protobuf":                                  Bp2BuildDefaultTrueRecursively,
+		"external/python/six":                                Bp2BuildDefaultTrueRecursively,
+		"external/scudo":                                     Bp2BuildDefaultTrueRecursively,
+		"external/zlib":                                      Bp2BuildDefaultTrueRecursively,
+		"frameworks/native/libs/adbd_auth":                   Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb":                               Bp2BuildDefaultTrue,
+		"packages/modules/adb/crypto":                        Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/libs":                          Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/pairing_auth":                  Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/pairing_connection":            Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/proto":                         Bp2BuildDefaultTrueRecursively,
+		"packages/modules/adb/tls":                           Bp2BuildDefaultTrueRecursively,
+		"prebuilts/clang/host/linux-x86":                     Bp2BuildDefaultTrueRecursively,
+		"system/core/diagnose_usb":                           Bp2BuildDefaultTrueRecursively,
+		"system/core/libasyncio":                             Bp2BuildDefaultTrue,
+		"system/core/libcrypto_utils":                        Bp2BuildDefaultTrueRecursively,
+		"system/core/libcutils":                              Bp2BuildDefaultTrueRecursively,
+		"system/core/libprocessgroup":                        Bp2BuildDefaultTrue,
 		"system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively,
-		"system/libbase":                  Bp2BuildDefaultTrueRecursively,
-		"system/logging/liblog":           Bp2BuildDefaultTrueRecursively,
-		"system/sepolicy/apex":            Bp2BuildDefaultTrueRecursively,
-		"system/timezone/apex":            Bp2BuildDefaultTrueRecursively,
-		"system/timezone/output_data":     Bp2BuildDefaultTrueRecursively,
-		"external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively,
-		"external/fmtlib":                 Bp2BuildDefaultTrueRecursively,
-		"external/jemalloc_new":           Bp2BuildDefaultTrueRecursively,
-		"external/libcxx":                 Bp2BuildDefaultTrueRecursively,
-		"external/libcxxabi":              Bp2BuildDefaultTrueRecursively,
-		"external/libcap":                 Bp2BuildDefaultTrueRecursively,
-		"external/scudo":                  Bp2BuildDefaultTrueRecursively,
-		"prebuilts/clang/host/linux-x86":  Bp2BuildDefaultTrueRecursively,
+		"system/libbase":                                     Bp2BuildDefaultTrueRecursively,
+		"system/logging/liblog":                              Bp2BuildDefaultTrueRecursively,
+		"system/sepolicy/apex":                               Bp2BuildDefaultTrueRecursively,
+		"system/timezone/apex":                               Bp2BuildDefaultTrueRecursively,
+		"system/timezone/output_data":                        Bp2BuildDefaultTrueRecursively,
 	}
 
 	// Per-module denylist to always opt modules out of both bp2build and mixed builds.
@@ -203,8 +223,8 @@
 		"libc_malloc_debug",           // http://b/186824339, cc_library_static, depends on //system/libbase:libbase (http://b/186823646)
 		"libc_malloc_debug_backtrace", // http://b/186824112, cc_library_static, depends on //external/libcxxabi:libc++demangle (http://b/186823773)
 
-		"libcutils",         // http://b/186827426, cc_library, depends on //system/core/libprocessgroup:libprocessgroup_headers (http://b/186826841)
-		"libcutils_sockets", // http://b/186826853, cc_library, depends on //system/libbase:libbase (http://b/186826479)
+		//"libcutils",         // http://b/186827426, cc_library, depends on //system/core/libprocessgroup:libprocessgroup_headers (http://b/186826841)
+		//"libcutils_sockets", // http://b/186826853, cc_library, depends on //system/libbase:libbase (http://b/186826479)
 
 		"liblinker_debuggerd_stub", // http://b/186824327, cc_library_static, depends on //external/zlib:libz (http://b/186823782)
 		//                                                               also depends on //system/libziparchive:libziparchive (http://b/186823656)
@@ -223,11 +243,13 @@
 		"libbase_ndk", // http://b/186826477, cc_library, no such target '//build/bazel/platforms/os:darwin' when --platforms //build/bazel/platforms:android_x86 is added
 		// libcxx
 		"libBionicBenchmarksUtils", // cc_library_static, fatal error: 'map' file not found, from libcxx
-		"libbase",                  // Depends on fmtlib via static_libs and also whole_static_libs, which results in bazel errors.
 
-		"libfdtrack", // depends on liblzma and libbase
+		"libprotobuf-python",               // contains .proto sources
+		"libprotobuf-internal-protos",      // we don't handle path property for fileegroups
+		"libprotobuf-internal-python-srcs", // we don't handle path property for fileegroups
 
-		"libseccomp_policy", // depends on libbase
+		"libseccomp_policy", // b/201094425: depends on func_to_syscall_nrs, which depends on py_binary, which is unsupported in mixed builds.
+		"libfdtrack",        // depends on libunwindstack, which depends on unsupported module art_cc_library_statics
 
 		"gwp_asan_crash_handler", // cc_library, ld.lld: error: undefined symbol: memset
 
@@ -249,6 +271,38 @@
 
 		// APEX support
 		"com.android.runtime", // http://b/194746715, apex, depends on 'libc_malloc_debug' and 'libc_malloc_hooks'
+
+		"libadb_crypto",                    // Depends on libadb_protos
+		"libadb_crypto_static",             // Depends on libadb_protos_static
+		"libadb_pairing_connection",        // Depends on libadb_protos
+		"libadb_pairing_connection_static", // Depends on libadb_protos_static
+		"libadb_pairing_server",            // Depends on libadb_protos
+		"libadb_pairing_server_static",     // Depends on libadb_protos_static
+		"libadbd",                          // Depends on libadbd_core
+		"libadbd_core",                     // Depends on libadb_protos
+		"libadbd_services",                 // Depends on libadb_protos
+
+		"libadb_protos_static",         // b/200601772: Requires cc_library proto support
+		"libadb_protos",                // b/200601772: Requires cc_library proto support
+		"libapp_processes_protos_lite", // b/200601772: Requires cc_library proto support
+
+		"libbase", // TODO(cparsons): Breaks libandroidfw. Investigate.
+
+		// The below items depend on libbase.
+		"libadb_pairing_auth",
+		"libadb_pairing_auth_static",
+		"libadb_sysdeps",
+		"libadb_tls_connection",
+		"libadb_tls_connection_static",
+		"libadbconnection_client",
+		"libadbconnection_server",
+		"libadbd_auth",
+		"libadbd_fs",
+		"libcutils",
+		"libcutils_sockets",
+		"libdiagnose_usb",
+		// ---
+
 	}
 
 	// Per-module denylist of cc_library modules to only generate the static
@@ -265,6 +319,7 @@
 		"libseccomp_policy_app_zygote_sources", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
 		"libseccomp_policy_app_sources",        // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
 		"libseccomp_policy_system_sources",     // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
+
 	}
 
 	// Used for quicker lookups
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index b5746f7..9957369 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -393,9 +393,19 @@
 	OutputPath
 }
 
+// ensure BazelOutPath implements Path
 var _ Path = BazelOutPath{}
+
+// ensure BazelOutPath implements genPathProvider
+var _ genPathProvider = BazelOutPath{}
+
+// ensure BazelOutPath implements objPathProvider
 var _ objPathProvider = BazelOutPath{}
 
+func (p BazelOutPath) genPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleGenPath {
+	return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
+}
+
 func (p BazelOutPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
 	return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
 }
diff --git a/apex/builder.go b/apex/builder.go
index 6df40f4..c05c20c 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -824,10 +824,8 @@
 		a.outputFile = signedCompressedOutputFile
 	}
 
-	// Install to $OUT/soong/{target,host}/.../apex
-	if a.installable() {
-		ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
-	}
+	// Install to $OUT/soong/{target,host}/.../apex.
+	ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
 
 	// installed-files.txt is dist'ed
 	a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index d59f8bf..55a9e42 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -103,6 +103,10 @@
 	// List of bootclasspath fragments inside this prebuilt APEX bundle and for which this APEX
 	// bundle will create an APEX variant.
 	Exported_bootclasspath_fragments []string
+
+	// List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this
+	// APEX bundle will create an APEX variant.
+	Exported_systemserverclasspath_fragments []string
 }
 
 // initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the
@@ -174,7 +178,8 @@
 		tag := ctx.OtherModuleDependencyTag(child)
 
 		name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child))
-		if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
+		if java.IsBootclasspathFragmentContentDepTag(tag) ||
+			java.IsSystemServerClasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag {
 			// If the exported java module provides a dex jar path then add it to the list of apexFiles.
 			path := child.(interface {
 				DexJarBuildPath() java.OptionalDexJarPath
@@ -194,8 +199,9 @@
 				}
 				p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
 			}
-		} else if tag == exportedBootclasspathFragmentTag {
-			// Visit the children of the bootclasspath_fragment.
+		} else if tag == exportedBootclasspathFragmentTag ||
+			tag == exportedSystemserverclasspathFragmentTag {
+			// Visit the children of the bootclasspath_fragment and systemserver_fragment.
 			return true
 		}
 
@@ -311,21 +317,31 @@
 	}
 }
 
+func (p *prebuiltCommon) getExportedDependencies() map[string]exportedDependencyTag {
+	dependencies := make(map[string]exportedDependencyTag)
+
+	for _, dep := range p.prebuiltCommonProperties.Exported_java_libs {
+		dependencies[dep] = exportedJavaLibTag
+	}
+
+	for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
+		dependencies[dep] = exportedBootclasspathFragmentTag
+	}
+
+	for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments {
+		dependencies[dep] = exportedSystemserverclasspathFragmentTag
+	}
+
+	return dependencies
+}
+
 // prebuiltApexContentsDeps adds dependencies onto the prebuilt apex module's contents.
 func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorContext) {
 	module := ctx.Module()
-	// Add dependencies onto the java modules that represent the java libraries that are provided by
-	// and exported from this prebuilt apex.
-	for _, exported := range p.prebuiltCommonProperties.Exported_java_libs {
-		dep := android.PrebuiltNameFromSource(exported)
-		ctx.AddDependency(module, exportedJavaLibTag, dep)
-	}
 
-	// Add dependencies onto the bootclasspath fragment modules that are exported from this prebuilt
-	// apex.
-	for _, exported := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments {
-		dep := android.PrebuiltNameFromSource(exported)
-		ctx.AddDependency(module, exportedBootclasspathFragmentTag, dep)
+	for dep, tag := range p.getExportedDependencies() {
+		prebuiltDep := android.PrebuiltNameFromSource(dep)
+		ctx.AddDependency(module, tag, prebuiltDep)
 	}
 }
 
@@ -576,9 +592,9 @@
 // A deapexer module is only needed when the prebuilt apex specifies one or more modules in either
 // the `exported_java_libs` or `exported_bootclasspath_fragments` properties as that indicates that
 // the listed modules need access to files from within the prebuilt .apex file.
-func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string, properties *PrebuiltCommonProperties) {
+func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerName string, apexFileSource string) {
 	// Only create the deapexer module if it is needed.
-	if len(properties.Exported_java_libs)+len(properties.Exported_bootclasspath_fragments) == 0 {
+	if len(p.getExportedDependencies()) == 0 {
 		return
 	}
 
@@ -674,8 +690,9 @@
 var _ android.RequiresFilesFromPrebuiltApexTag = exportedDependencyTag{}
 
 var (
-	exportedJavaLibTag               = exportedDependencyTag{name: "exported_java_libs"}
-	exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
+	exportedJavaLibTag                       = exportedDependencyTag{name: "exported_java_libs"}
+	exportedBootclasspathFragmentTag         = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
+	exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"}
 )
 
 var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
@@ -716,7 +733,7 @@
 	createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
 
 	apexFileSource := ":" + apexSelectorModuleName
-	createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, p.prebuiltCommonProperties)
+	p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
 
 	// Add a source reference to retrieve the selected apex from the selector module.
 	p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -919,7 +936,7 @@
 	createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
 
 	apexFileSource := ":" + apexExtractorModuleName
-	createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource, a.prebuiltCommonProperties)
+	a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(baseModuleName), apexFileSource)
 
 	// After passing the arch specific src properties to the creating the apex selector module
 	a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index a8d5931..dc682fa 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -181,3 +181,53 @@
 			}
 		`)
 }
+
+func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForTestWithSystemserverclasspathFragment,
+		prepareForTestWithMyapex,
+		dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
+	).RunTestWithBp(t, `
+		prebuilt_apex {
+			name: "myapex",
+			arch: {
+				arm64: {
+					src: "myapex-arm64.apex",
+				},
+				arm: {
+					src: "myapex-arm.apex",
+				},
+			},
+			exported_systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+		}
+
+		java_import {
+			name: "foo",
+			jars: ["foo.jar"],
+			apex_available: [
+				"myapex",
+			],
+		}
+
+		prebuilt_systemserverclasspath_fragment {
+			name: "mysystemserverclasspathfragment",
+			prefer: true,
+			contents: [
+				"foo",
+			],
+			apex_available: [
+				"myapex",
+			],
+		}
+	`)
+
+	java.CheckModuleDependencies(t, result.TestContext, "myapex", "android_common_myapex", []string{
+		`myapex.apex.selector`,
+		`prebuilt_mysystemserverclasspathfragment`,
+	})
+
+	java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{
+		`myapex.deapexer`,
+		`prebuilt_foo`,
+	})
+}
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index b0a88ae..63a0b8a 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -71,6 +71,7 @@
         ".",
     ],
     srcs = ["a/b/c.c"],
+    system_dynamic_deps = [],
 )`,
 		},
 	})
@@ -116,6 +117,7 @@
     ],
     local_includes = ["."],
     srcs = ["a/b/c.c"],
+    system_dynamic_deps = [],
 )`,
 		}})
 }
@@ -149,11 +151,13 @@
     name = "bar",
     copts = ["-fno-addrsig"],
     srcs = ["x/y/z.c"],
+    system_dynamic_deps = [],
 )`, `cc_object(
     name = "foo",
     copts = ["-fno-addrsig"],
     deps = [":bar"],
     srcs = ["a/b/c.c"],
+    system_dynamic_deps = [],
 )`,
 		},
 	})
@@ -180,6 +184,7 @@
     name = "foo",
     copts = ["-fno-addrsig"],
     srcs = ["a/b/c.c"],
+    system_dynamic_deps = [],
 )`,
 		},
 	})
@@ -211,6 +216,7 @@
     }),
     copts = ["-fno-addrsig"],
     srcs_as = ["src.S"],
+    system_dynamic_deps = [],
 )`,
 		},
 	})
@@ -248,6 +254,7 @@
         "//build/bazel/platforms/arch:arm": ["arch/arm/file.cpp"],
         "//conditions:default": [],
     }),
+    system_dynamic_deps = [],
 )`,
 		},
 	})
@@ -301,30 +308,126 @@
         "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
         "//conditions:default": [],
     }),
+    system_dynamic_deps = [],
 )`,
 		},
 	})
 }
 
-func TestCcObjectCflagsMultiOs(t *testing.T) {
+func TestCcObjectLinkerScript(t *testing.T) {
 	runCcObjectTestCase(t, bp2buildTestCase{
-		description:                        "cc_object setting cflags for multiple OSes",
+		description:                        "cc_object setting linker_script",
 		moduleTypeUnderTest:                "cc_object",
 		moduleTypeUnderTestFactory:         cc.ObjectFactory,
 		moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
 		blueprint: `cc_object {
     name: "foo",
+    srcs: ["base.cpp"],
+    linker_script: "bunny.lds",
+    include_build_directory: false,
+}
+`,
+		expectedBazelTargets: []string{
+			`cc_object(
+    name = "foo",
+    copts = ["-fno-addrsig"],
+    linker_script = "bunny.lds",
+    srcs = ["base.cpp"],
+)`,
+		},
+	})
+}
+
+func TestCcObjectDepsAndLinkerScriptSelects(t *testing.T) {
+	runCcObjectTestCase(t, bp2buildTestCase{
+		description:                        "cc_object setting deps and linker_script across archs",
+		moduleTypeUnderTest:                "cc_object",
+		moduleTypeUnderTestFactory:         cc.ObjectFactory,
+		moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+		blueprint: `cc_object {
+    name: "foo",
+    srcs: ["base.cpp"],
+    arch: {
+        x86: {
+            objs: ["x86_obj"],
+            linker_script: "x86.lds",
+        },
+        x86_64: {
+            objs: ["x86_64_obj"],
+            linker_script: "x86_64.lds",
+        },
+        arm: {
+            objs: ["arm_obj"],
+            linker_script: "arm.lds",
+        },
+    },
+    include_build_directory: false,
+}
+
+cc_object {
+    name: "x86_obj",
     system_shared_libs: [],
+    srcs: ["x86.cpp"],
+    include_build_directory: false,
+    bazel_module: { bp2build_available: false },
+}
+
+cc_object {
+    name: "x86_64_obj",
+    system_shared_libs: [],
+    srcs: ["x86_64.cpp"],
+    include_build_directory: false,
+    bazel_module: { bp2build_available: false },
+}
+
+cc_object {
+    name: "arm_obj",
+    system_shared_libs: [],
+    srcs: ["arm.cpp"],
+    include_build_directory: false,
+    bazel_module: { bp2build_available: false },
+}
+`,
+		expectedBazelTargets: []string{
+			`cc_object(
+    name = "foo",
+    copts = ["-fno-addrsig"],
+    deps = select({
+        "//build/bazel/platforms/arch:arm": [":arm_obj"],
+        "//build/bazel/platforms/arch:x86": [":x86_obj"],
+        "//build/bazel/platforms/arch:x86_64": [":x86_64_obj"],
+        "//conditions:default": [],
+    }),
+    linker_script = select({
+        "//build/bazel/platforms/arch:arm": "arm.lds",
+        "//build/bazel/platforms/arch:x86": "x86.lds",
+        "//build/bazel/platforms/arch:x86_64": "x86_64.lds",
+        "//conditions:default": None,
+    }),
+    srcs = ["base.cpp"],
+)`,
+		},
+	})
+}
+
+func TestCcObjectSelectOnLinuxAndBionicArchs(t *testing.T) {
+	runCcObjectTestCase(t, bp2buildTestCase{
+		description:                        "cc_object setting srcs based on linux and bionic archs",
+		moduleTypeUnderTest:                "cc_object",
+		moduleTypeUnderTestFactory:         cc.ObjectFactory,
+		moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+		blueprint: `cc_object {
+    name: "foo",
     srcs: ["base.cpp"],
     target: {
-        android: {
-            cflags: ["-fPIC"],
+        linux_arm64: {
+            srcs: ["linux_arm64.cpp",]
         },
-        windows: {
-            cflags: ["-fPIC"],
+        linux_x86: {
+            srcs: ["linux_x86.cpp",]
         },
-        darwin: {
-            cflags: ["-Wall"],
+        bionic_arm64: {
+            srcs: ["bionic_arm64.cpp",]
         },
     },
     include_build_directory: false,
@@ -333,13 +436,21 @@
 		expectedBazelTargets: []string{
 			`cc_object(
     name = "foo",
-    copts = ["-fno-addrsig"] + select({
-        "//build/bazel/platforms/os:android": ["-fPIC"],
-        "//build/bazel/platforms/os:darwin": ["-Wall"],
-        "//build/bazel/platforms/os:windows": ["-fPIC"],
+    copts = ["-fno-addrsig"],
+    srcs = ["base.cpp"] + select({
+        "//build/bazel/platforms/os_arch:android_arm64": [
+            "bionic_arm64.cpp",
+            "linux_arm64.cpp",
+        ],
+        "//build/bazel/platforms/os_arch:android_x86": ["linux_x86.cpp"],
+        "//build/bazel/platforms/os_arch:linux_bionic_arm64": [
+            "bionic_arm64.cpp",
+            "linux_arm64.cpp",
+        ],
+        "//build/bazel/platforms/os_arch:linux_glibc_x86": ["linux_x86.cpp"],
+        "//build/bazel/platforms/os_arch:linux_musl_x86": ["linux_x86.cpp"],
         "//conditions:default": [],
     }),
-    srcs = ["base.cpp"],
 )`,
 		},
 	})
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 84c3a86..4c9f579 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3869,10 +3869,99 @@
 }
 
 func TestIncludeDirectoryOrdering(t *testing.T) {
-	bp := `
+	baseExpectedFlags := []string{
+		"${config.ArmThumbCflags}",
+		"${config.ArmCflags}",
+		"${config.CommonGlobalCflags}",
+		"${config.DeviceGlobalCflags}",
+		"${config.ExternalCflags}",
+		"${config.ArmToolchainCflags}",
+		"${config.ArmArmv7ANeonCflags}",
+		"${config.ArmGenericCflags}",
+		"-target",
+		"armv7a-linux-androideabi20",
+		"-B${config.ArmGccRoot}/arm-linux-androideabi/bin",
+	}
+
+	expectedIncludes := []string{
+		"external/foo/android_arm_export_include_dirs",
+		"external/foo/lib32_export_include_dirs",
+		"external/foo/arm_export_include_dirs",
+		"external/foo/android_export_include_dirs",
+		"external/foo/linux_export_include_dirs",
+		"external/foo/export_include_dirs",
+		"external/foo/android_arm_local_include_dirs",
+		"external/foo/lib32_local_include_dirs",
+		"external/foo/arm_local_include_dirs",
+		"external/foo/android_local_include_dirs",
+		"external/foo/linux_local_include_dirs",
+		"external/foo/local_include_dirs",
+		"external/foo",
+		"external/foo/libheader1",
+		"external/foo/libheader2",
+		"external/foo/libwhole1",
+		"external/foo/libwhole2",
+		"external/foo/libstatic1",
+		"external/foo/libstatic2",
+		"external/foo/libshared1",
+		"external/foo/libshared2",
+		"external/foo/liblinux",
+		"external/foo/libandroid",
+		"external/foo/libarm",
+		"external/foo/lib32",
+		"external/foo/libandroid_arm",
+		"defaults/cc/common/ndk_libc++_shared",
+		"defaults/cc/common/ndk_libandroid_support",
+	}
+
+	conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
+	cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
+
+	cflags := []string{"-Wall", "-Werror"}
+	cstd := []string{"-std=gnu99"}
+	cppstd := []string{"-std=gnu++17", "-fno-rtti"}
+
+	lastIncludes := []string{
+		"out/soong/ndk/sysroot/usr/include",
+		"out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
+	}
+
+	combineSlices := func(slices ...[]string) []string {
+		var ret []string
+		for _, s := range slices {
+			ret = append(ret, s...)
+		}
+		return ret
+	}
+
+	testCases := []struct {
+		name     string
+		src      string
+		expected []string
+	}{
+		{
+			name:     "c",
+			src:      "foo.c",
+			expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}"}),
+		},
+		{
+			name:     "cc",
+			src:      "foo.cc",
+			expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}"}),
+		},
+		{
+			name:     "assemble",
+			src:      "foo.s",
+			expected: combineSlices(baseExpectedFlags, []string{"-D__ASSEMBLY__"}, expectedIncludes, lastIncludes),
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(t *testing.T) {
+			bp := fmt.Sprintf(`
 		cc_library {
 			name: "libfoo",
-			srcs: ["foo.c"],
+			srcs: ["%s"],
 			local_include_dirs: ["local_include_dirs"],
 			export_include_dirs: ["export_include_dirs"],
 			export_system_include_dirs: ["export_system_include_dirs"],
@@ -3928,24 +4017,24 @@
 			sdk_version: "20",
 			stl: "none",
 		}
-	`
+	`, tc.src)
 
-	libs := []string{
-		"libstatic1",
-		"libstatic2",
-		"libwhole1",
-		"libwhole2",
-		"libshared1",
-		"libshared2",
-		"libandroid",
-		"libandroid_arm",
-		"liblinux",
-		"lib32",
-		"libarm",
-	}
+			libs := []string{
+				"libstatic1",
+				"libstatic2",
+				"libwhole1",
+				"libwhole2",
+				"libshared1",
+				"libshared2",
+				"libandroid",
+				"libandroid_arm",
+				"liblinux",
+				"lib32",
+				"libarm",
+			}
 
-	for _, lib := range libs {
-		bp += fmt.Sprintf(`
+			for _, lib := range libs {
+				bp += fmt.Sprintf(`
 			cc_library {
 				name: "%s",
 				export_include_dirs: ["%s"],
@@ -3953,69 +4042,30 @@
 				stl: "none",
 			}
 		`, lib, lib)
+			}
+
+			ctx := android.GroupFixturePreparers(
+				PrepareForIntegrationTestWithCc,
+				android.FixtureAddTextFile("external/foo/Android.bp", bp),
+			).RunTest(t)
+			// Use the arm variant instead of the arm64 variant so that it gets headers from
+			// ndk_libandroid_support to test LateStaticLibs.
+			cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
+
+			var includes []string
+			flags := strings.Split(cflags, " ")
+			for _, flag := range flags {
+				if strings.HasPrefix(flag, "-I") {
+					includes = append(includes, strings.TrimPrefix(flag, "-I"))
+				} else if flag == "-isystem" {
+					// skip isystem, include next
+				} else if len(flag) > 0 {
+					includes = append(includes, flag)
+				}
+			}
+
+			android.AssertArrayString(t, "includes", tc.expected, includes)
+		})
 	}
 
-	ctx := android.GroupFixturePreparers(
-		PrepareForIntegrationTestWithCc,
-		android.FixtureAddTextFile("external/foo/Android.bp", bp),
-	).RunTest(t)
-	// Use the arm variant instead of the arm64 variant so that it gets headers from
-	// ndk_libandroid_support to test LateStaticLibs.
-	cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
-
-	var includes []string
-	flags := strings.Split(cflags, " ")
-	for i, flag := range flags {
-		if strings.Contains(flag, "Cflags") {
-			includes = append(includes, flag)
-		} else if strings.HasPrefix(flag, "-I") {
-			includes = append(includes, strings.TrimPrefix(flag, "-I"))
-		} else if flag == "-isystem" {
-			includes = append(includes, flags[i+1])
-		}
-	}
-
-	want := []string{
-		"${config.ArmThumbCflags}",
-		"${config.ArmCflags}",
-		"${config.CommonGlobalCflags}",
-		"${config.DeviceGlobalCflags}",
-		"${config.ExternalCflags}",
-		"${config.ArmToolchainCflags}",
-		"${config.ArmArmv7ANeonCflags}",
-		"${config.ArmGenericCflags}",
-		"external/foo/android_arm_export_include_dirs",
-		"external/foo/lib32_export_include_dirs",
-		"external/foo/arm_export_include_dirs",
-		"external/foo/android_export_include_dirs",
-		"external/foo/linux_export_include_dirs",
-		"external/foo/export_include_dirs",
-		"external/foo/android_arm_local_include_dirs",
-		"external/foo/lib32_local_include_dirs",
-		"external/foo/arm_local_include_dirs",
-		"external/foo/android_local_include_dirs",
-		"external/foo/linux_local_include_dirs",
-		"external/foo/local_include_dirs",
-		"external/foo",
-		"external/foo/libheader1",
-		"external/foo/libheader2",
-		"external/foo/libwhole1",
-		"external/foo/libwhole2",
-		"external/foo/libstatic1",
-		"external/foo/libstatic2",
-		"external/foo/libshared1",
-		"external/foo/libshared2",
-		"external/foo/liblinux",
-		"external/foo/libandroid",
-		"external/foo/libarm",
-		"external/foo/lib32",
-		"external/foo/libandroid_arm",
-		"defaults/cc/common/ndk_libc++_shared",
-		"defaults/cc/common/ndk_libandroid_support",
-		"out/soong/ndk/sysroot/usr/include",
-		"out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
-		"${config.NoOverrideGlobalCflags}",
-	}
-
-	android.AssertArrayString(t, "includes", want, includes)
 }
diff --git a/cc/object.go b/cc/object.go
index 99b257a..4ec2b19 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -122,14 +122,17 @@
 
 // For bp2build conversion.
 type bazelObjectAttributes struct {
-	Srcs              bazel.LabelListAttribute
-	Srcs_as           bazel.LabelListAttribute
-	Hdrs              bazel.LabelListAttribute
-	Deps              bazel.LabelListAttribute
-	Copts             bazel.StringListAttribute
-	Asflags           bazel.StringListAttribute
-	Local_includes    bazel.StringListAttribute
-	Absolute_includes bazel.StringListAttribute
+	Srcs                bazel.LabelListAttribute
+	Srcs_as             bazel.LabelListAttribute
+	Hdrs                bazel.LabelListAttribute
+	Deps                bazel.LabelListAttribute
+	System_dynamic_deps bazel.LabelListAttribute
+	Copts               bazel.StringListAttribute
+	Asflags             bazel.StringListAttribute
+	Local_includes      bazel.StringListAttribute
+	Absolute_includes   bazel.StringListAttribute
+	Stl                 *string
+	Linker_script       bazel.LabelAttribute
 }
 
 // ObjectBp2Build is the bp2build converter from cc_object modules to the
@@ -153,12 +156,26 @@
 	// Set arch-specific configurable attributes
 	compilerAttrs := bp2BuildParseCompilerProps(ctx, m)
 	var deps bazel.LabelListAttribute
-	for _, props := range m.linker.linkerProps() {
-		if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
-			deps = bazel.MakeLabelListAttribute(
-				android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
+	systemDynamicDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
+
+	var linkerScript bazel.LabelAttribute
+
+	for axis, configToProps := range m.GetArchVariantProperties(ctx, &ObjectLinkerProperties{}) {
+		for config, props := range configToProps {
+			if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
+				if objectLinkerProps.Linker_script != nil {
+					linkerScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script))
+				}
+				deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
+				systemSharedLibs := objectLinkerProps.System_shared_libs
+				if len(systemSharedLibs) > 0 {
+					systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs)
+				}
+				systemDynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
+			}
 		}
 	}
+	deps.ResolveExcludes()
 
 	// Don't split cc_object srcs across languages. Doing so would add complexity,
 	// and this isn't typically done for cc_object.
@@ -172,13 +189,16 @@
 	}
 
 	attrs := &bazelObjectAttributes{
-		Srcs:              srcs,
-		Srcs_as:           compilerAttrs.asSrcs,
-		Deps:              deps,
-		Copts:             compilerAttrs.copts,
-		Asflags:           asFlags,
-		Local_includes:    compilerAttrs.localIncludes,
-		Absolute_includes: compilerAttrs.absoluteIncludes,
+		Srcs:                srcs,
+		Srcs_as:             compilerAttrs.asSrcs,
+		Deps:                deps,
+		System_dynamic_deps: systemDynamicDeps,
+		Copts:               compilerAttrs.copts,
+		Asflags:             asFlags,
+		Local_includes:      compilerAttrs.localIncludes,
+		Absolute_includes:   compilerAttrs.absoluteIncludes,
+		Stl:                 compilerAttrs.stl,
+		Linker_script:       linkerScript,
 	}
 
 	props := bazel.BazelTargetModuleProperties{
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index be81487..f8844fc 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -663,23 +663,6 @@
     name = "{{.BpName}}",
     {{.BazelImportProperty}} = {{- if not .IsAar}}[{{- end}}"{{.ArtifactFile}}"{{- if not .IsAar}}]{{- end}},
     visibility = ["//visibility:public"],
-    deps = [
-        {{- range .BazelJarDeps}}
-        "{{.}}",
-        {{- end}}
-        {{- range .BazelAarDeps}}
-        "{{.}}",
-        {{- end}}
-        {{- range .BpExtraStaticLibs}}
-        "{{.}}",
-        {{- end}}
-        {{- range .BpExtraLibs}}
-        "{{.}}",
-        {{- end}}
-        {{- range .BpOptionalUsesLibs}}
-        "{{.}}",
-        {{- end}}
-    ],
     exports = [
         {{- range .BazelJarDeps}}
         "{{.}}",
diff --git a/java/java.go b/java/java.go
index 94c12bd..23809df 100644
--- a/java/java.go
+++ b/java/java.go
@@ -73,6 +73,7 @@
 	android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType)
 	android.RegisterSdkMemberType(javaLibsSdkMemberType)
 	android.RegisterSdkMemberType(javaBootLibsSdkMemberType)
+	android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType)
 	android.RegisterSdkMemberType(javaTestSdkMemberType)
 }
 
@@ -146,6 +147,37 @@
 		onlyCopyJarToSnapshot,
 	}
 
+	// Supports adding java systemserver libraries to module_exports and sdk.
+	//
+	// The build has some implicit dependencies (via the systemserver jars configuration) on a number
+	// of modules that are part of the java systemserver classpath and which are provided by mainline
+	// modules but which are not otherwise used outside those mainline modules.
+	//
+	// As they are not needed outside the mainline modules adding them to the sdk/module-exports as
+	// either java_libs, or java_header_libs would end up exporting more information than was strictly
+	// necessary. The java_systemserver_libs property to allow those modules to be exported as part of
+	// the sdk/module_exports without exposing any unnecessary information.
+	javaSystemserverLibsSdkMemberType = &librarySdkMemberType{
+		android.SdkMemberTypeBase{
+			PropertyName: "java_systemserver_libs",
+			SupportsSdk:  true,
+		},
+		func(ctx android.SdkMemberContext, j *Library) android.Path {
+			// Java systemserver libs are only provided in the SDK to provide access to their dex
+			// implementation jar for use by dexpreopting. They do not need to provide an actual
+			// implementation jar but the java_import will need a file that exists so just copy an empty
+			// file. Any attempt to use that file as a jar will cause a build error.
+			return ctx.SnapshotBuilder().EmptyFile()
+		},
+		func(osPrefix, name string) string {
+			// Create a special name for the implementation jar to try and provide some useful information
+			// to a developer that attempts to compile against this.
+			// TODO(b/175714559): Provide a proper error message in Soong not ninja.
+			return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix)
+		},
+		onlyCopyJarToSnapshot,
+	}
+
 	// Supports adding java test libraries to module_exports but not sdk.
 	javaTestSdkMemberType = &testSdkMemberType{
 		SdkMemberTypeBase: android.SdkMemberTypeBase{
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index de2a978..1b4fda8 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -23,11 +23,19 @@
 
 func init() {
 	registerSystemserverClasspathBuildComponents(android.InitRegistrationContext)
+
+	android.RegisterSdkMemberType(&systemServerClasspathFragmentMemberType{
+		SdkMemberTypeBase: android.SdkMemberTypeBase{
+			PropertyName: "systemserverclasspath_fragments",
+			SupportsSdk:  true,
+		},
+	})
 }
 
 func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("platform_systemserverclasspath", platformSystemServerClasspathFactory)
 	ctx.RegisterModuleType("systemserverclasspath_fragment", systemServerClasspathFactory)
+	ctx.RegisterModuleType("prebuilt_systemserverclasspath_fragment", prebuiltSystemServerClasspathModuleFactory)
 }
 
 type platformSystemServerClasspathModule struct {
@@ -61,6 +69,7 @@
 type SystemServerClasspathModule struct {
 	android.ModuleBase
 	android.ApexModuleBase
+	android.SdkBase
 
 	ClasspathFragmentBase
 
@@ -85,6 +94,7 @@
 	m := &SystemServerClasspathModule{}
 	m.AddProperties(&m.properties)
 	android.InitApexModule(m)
+	android.InitSdkAwareModule(m)
 	initClasspathFragment(m, SYSTEMSERVERCLASSPATH)
 	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
 	return m
@@ -112,7 +122,7 @@
 	_, unknown = android.RemoveFromList("geotz", unknown)
 
 	// For non test apexes, make sure that all contents are actually declared in make.
-	if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 {
+	if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
 		ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS", unknown)
 	}
 
@@ -128,12 +138,33 @@
 	return false
 }
 
+// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if
+// they were specified using java_systemserver_libs or java_sdk_libs.
+func (b systemServerClasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
+	// If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs
+	// property, otherwise treat if it was specified in the java_systemserver_libs property.
+	if javaSdkLibrarySdkMemberType.IsInstance(child) {
+		return javaSdkLibrarySdkMemberType
+	}
+
+	return javaSystemserverLibsSdkMemberType
+}
+
+func (b systemServerClasspathFragmentContentDependencyTag) ExportMember() bool {
+	return true
+}
+
 // Contents of system server fragments in an apex are considered to be directly in the apex, as if
 // they were listed in java_libs.
 func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {}
 
+// Contents of system server fragments require files from prebuilt apex files.
+func (systemServerClasspathFragmentContentDependencyTag) RequiresFilesFromPrebuiltApex() {}
+
 var _ android.ReplaceSourceWithPrebuilt = systemServerClasspathFragmentContentDepTag
+var _ android.SdkMemberDependencyTag = systemServerClasspathFragmentContentDepTag
 var _ android.CopyDirectlyInAnyApexTag = systemServerClasspathFragmentContentDepTag
+var _ android.RequiresFilesFromPrebuiltApexTag = systemServerClasspathFragmentContentDepTag
 
 // The tag used for the dependency between the systemserverclasspath_fragment module and its contents.
 var systemServerClasspathFragmentContentDepTag = systemServerClasspathFragmentContentDependencyTag{}
@@ -144,8 +175,14 @@
 
 func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
 	module := ctx.Module()
+	_, isSourceModule := module.(*SystemServerClasspathModule)
 
 	for _, name := range s.properties.Contents {
+		// A systemserverclasspath_fragment must depend only on other source modules, while the
+		// prebuilt_systemserverclasspath_fragment_fragment must only depend on other prebuilt modules.
+		if !isSourceModule {
+			name = android.PrebuiltNameFromSource(name)
+		}
 		ctx.AddDependency(module, systemServerClasspathFragmentContentDepTag, name)
 	}
 }
@@ -155,3 +192,80 @@
 	dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...)
 	dpInfo.Paths = append(dpInfo.Paths, s.modulePaths...)
 }
+
+type systemServerClasspathFragmentMemberType struct {
+	android.SdkMemberTypeBase
+}
+
+func (s *systemServerClasspathFragmentMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
+	ctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (s *systemServerClasspathFragmentMemberType) IsInstance(module android.Module) bool {
+	_, ok := module.(*SystemServerClasspathModule)
+	return ok
+}
+
+func (s *systemServerClasspathFragmentMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
+	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_systemserverclasspath_fragment")
+}
+
+func (s *systemServerClasspathFragmentMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
+	return &systemServerClasspathFragmentSdkMemberProperties{}
+}
+
+type systemServerClasspathFragmentSdkMemberProperties struct {
+	android.SdkMemberPropertiesBase
+
+	// Contents of the systemserverclasspath fragment
+	Contents []string
+}
+
+func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
+	module := variant.(*SystemServerClasspathModule)
+
+	s.Contents = module.properties.Contents
+}
+
+func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
+	builder := ctx.SnapshotBuilder()
+	requiredMemberDependency := builder.SdkMemberReferencePropertyTag(true)
+
+	if len(s.Contents) > 0 {
+		propertySet.AddPropertyWithTag("contents", s.Contents, requiredMemberDependency)
+	}
+}
+
+var _ android.SdkMemberType = (*systemServerClasspathFragmentMemberType)(nil)
+
+// A prebuilt version of the systemserverclasspath_fragment module.
+type prebuiltSystemServerClasspathModule struct {
+	SystemServerClasspathModule
+	prebuilt android.Prebuilt
+}
+
+func (module *prebuiltSystemServerClasspathModule) Prebuilt() *android.Prebuilt {
+	return &module.prebuilt
+}
+
+func (module *prebuiltSystemServerClasspathModule) Name() string {
+	return module.prebuilt.Name(module.ModuleBase.Name())
+}
+
+func (module *prebuiltSystemServerClasspathModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
+	return nil
+}
+
+var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltSystemServerClasspathModule)(nil)
+
+func prebuiltSystemServerClasspathModuleFactory() android.Module {
+	m := &prebuiltSystemServerClasspathModule{}
+	m.AddProperties(&m.properties)
+	// This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
+	// array.
+	android.InitPrebuiltModule(m, &[]string{"placeholder"})
+	android.InitApexModule(m)
+	android.InitSdkAwareModule(m)
+	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+	return m
+}
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index b9b7e2c..3ae8ab9 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -726,7 +726,7 @@
 func (ctx *parseContext) newDependentModule(path string, optional bool) *moduleInfo {
 	modulePath := ctx.loadedModulePath(path)
 	if mi, ok := ctx.dependentModules[modulePath]; ok {
-		mi.optional = mi.optional || optional
+		mi.optional = mi.optional && optional
 		return mi
 	}
 	moduleName := moduleNameForFile(path)
@@ -753,16 +753,21 @@
 
 	// In a simple case, the name of a module to inherit/include is known statically.
 	if path, ok := maybeString(pathExpr); ok {
+		// Note that even if this directive loads a module unconditionally, a module may be
+		// absent without causing any harm if this directive is inside an if/else block.
+		moduleShouldExist := loadAlways && ctx.ifNestLevel == 0
 		if strings.Contains(path, "*") {
 			if paths, err := fs.Glob(ctx.script.sourceFS, path); err == nil {
 				for _, p := range paths {
-					processModule(inheritedStaticModule{ctx.newDependentModule(p, !loadAlways), loadAlways})
+					mi := ctx.newDependentModule(p, !moduleShouldExist)
+					processModule(inheritedStaticModule{mi, loadAlways})
 				}
 			} else {
 				ctx.errorf(v, "cannot glob wildcard argument")
 			}
 		} else {
-			processModule(inheritedStaticModule{ctx.newDependentModule(path, !loadAlways), loadAlways})
+			mi := ctx.newDependentModule(path, !moduleShouldExist)
+			processModule(inheritedStaticModule{mi, loadAlways})
 		}
 		return
 	}
@@ -852,13 +857,13 @@
 
 func (ctx *parseContext) handleInheritModule(v mkparser.Node, pathExpr starlarkExpr, loadAlways bool) {
 	ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) {
-		ctx.receiver.newNode(&inheritNode{im})
+		ctx.receiver.newNode(&inheritNode{im, loadAlways})
 	})
 }
 
 func (ctx *parseContext) handleInclude(v mkparser.Node, pathExpr starlarkExpr, loadAlways bool) {
 	ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) {
-		ctx.receiver.newNode(&includeNode{im})
+		ctx.receiver.newNode(&includeNode{im, loadAlways})
 	})
 }
 
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index ca7fe6f..434500b 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -120,22 +120,25 @@
 		desc:   "Inherit configuration always",
 		mkname: "product.mk",
 		in: `
-ifdef PRODUCT_NAME
 $(call inherit-product, part.mk)
+ifdef PRODUCT_NAME
+$(call inherit-product, part1.mk)
 else # Comment
-$(call inherit-product, $(LOCAL_PATH)/part.mk)
+$(call inherit-product, $(LOCAL_PATH)/part1.mk)
 endif
 `,
 		expected: `load("//build/make/core:product_config.rbc", "rblf")
 load(":part.star", _part_init = "init")
+load(":part1.star|init", _part1_init = "init")
 
 def init(g, handle):
   cfg = rblf.cfg(handle)
+  rblf.inherit(handle, "part", _part_init)
   if g.get("PRODUCT_NAME") != None:
-    rblf.inherit(handle, "part", _part_init)
+    rblf.inherit(handle, "part1", _part1_init)
   else:
     # Comment
-    rblf.inherit(handle, "part", _part_init)
+    rblf.inherit(handle, "part1", _part1_init)
 `,
 	},
 	{
@@ -158,22 +161,25 @@
 		desc:   "Include configuration",
 		mkname: "product.mk",
 		in: `
-ifdef PRODUCT_NAME
 include part.mk
+ifdef PRODUCT_NAME
+include part1.mk
 else
--include $(LOCAL_PATH)/part.mk)
+-include $(LOCAL_PATH)/part1.mk)
 endif
 `,
 		expected: `load("//build/make/core:product_config.rbc", "rblf")
-load(":part.star|init", _part_init = "init")
+load(":part.star", _part_init = "init")
+load(":part1.star|init", _part1_init = "init")
 
 def init(g, handle):
   cfg = rblf.cfg(handle)
+  _part_init(g, handle)
   if g.get("PRODUCT_NAME") != None:
-    _part_init(g, handle)
+    _part1_init(g, handle)
   else:
-    if _part_init != None:
-      _part_init(g, handle)
+    if _part1_init != None:
+      _part1_init(g, handle)
 `,
 	},
 
diff --git a/mk2rbc/node.go b/mk2rbc/node.go
index 8efe207..3fe1a17 100644
--- a/mk2rbc/node.go
+++ b/mk2rbc/node.go
@@ -57,7 +57,7 @@
 	name() string
 	entryName() string
 	emitSelect(gctx *generationContext)
-	isLoadAlways() bool
+	shouldExist() bool
 }
 
 type inheritedStaticModule struct {
@@ -72,7 +72,7 @@
 func (im inheritedStaticModule) emitSelect(_ *generationContext) {
 }
 
-func (im inheritedStaticModule) isLoadAlways() bool {
+func (im inheritedStaticModule) shouldExist() bool {
 	return im.loadAlways
 }
 
@@ -115,12 +115,13 @@
 	}
 }
 
-func (i inheritedDynamicModule) isLoadAlways() bool {
+func (i inheritedDynamicModule) shouldExist() bool {
 	return i.loadAlways
 }
 
 type inheritNode struct {
-	module inheritedModule
+	module     inheritedModule
+	loadAlways bool
 }
 
 func (inn *inheritNode) emit(gctx *generationContext) {
@@ -134,7 +135,7 @@
 	name := inn.module.name()
 	entry := inn.module.entryName()
 	gctx.newLine()
-	if inn.module.isLoadAlways() {
+	if inn.loadAlways {
 		gctx.writef("%s(handle, %s, %s)", cfnInherit, name, entry)
 		return
 	}
@@ -147,14 +148,15 @@
 }
 
 type includeNode struct {
-	module inheritedModule
+	module     inheritedModule
+	loadAlways bool
 }
 
 func (inn *includeNode) emit(gctx *generationContext) {
 	inn.module.emitSelect(gctx)
 	entry := inn.module.entryName()
 	gctx.newLine()
-	if inn.module.isLoadAlways() {
+	if inn.loadAlways {
 		gctx.writef("%s(g, handle)", entry)
 		return
 	}
diff --git a/rust/rust.go b/rust/rust.go
index 0a7d68d..b9afc7f 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -663,7 +663,7 @@
 }
 
 func (mod *Module) installable(apexInfo android.ApexInfo) bool {
-	if !mod.EverInstallable() {
+	if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) {
 		return false
 	}
 
diff --git a/sdk/Android.bp b/sdk/Android.bp
index c6544d6..acb9dbb 100644
--- a/sdk/Android.bp
+++ b/sdk/Android.bp
@@ -11,6 +11,7 @@
         "soong-android",
         "soong-apex",
         "soong-cc",
+        "soong-dexpreopt",
         "soong-java",
     ],
     srcs: [
@@ -31,6 +32,7 @@
         "license_sdk_test.go",
         "member_trait_test.go",
         "sdk_test.go",
+        "systemserverclasspath_fragment_sdk_test.go",
         "testing.go",
     ],
     pluginFor: ["soong_build"],
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 2b53739..0d9b4a0 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -482,6 +482,71 @@
 	)
 }
 
+func TestSnapshotWithJavaSystemserverLibrary(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForSdkTestWithJava,
+		android.FixtureAddFile("aidl", nil),
+		android.FixtureAddFile("resource.txt", nil),
+	).RunTestWithBp(t, `
+		module_exports {
+			name: "myexports",
+			java_systemserver_libs: ["myjavalib"],
+		}
+
+		java_library {
+			name: "myjavalib",
+			srcs: ["Test.java"],
+			java_resources: ["resource.txt"],
+			// The aidl files should not be copied to the snapshot because a java_systemserver_libs member
+			// is not intended to be used for compiling Java, only for accessing the dex implementation
+			// jar.
+			aidl: {
+				export_include_dirs: ["aidl"],
+			},
+			system_modules: "none",
+			sdk_version: "none",
+			compile_dex: true,
+			permitted_packages: ["pkg.myjavalib"],
+		}
+	`)
+
+	CheckSnapshot(t, result, "myexports", "",
+		checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+    name: "myjavalib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"],
+    permitted_packages: ["pkg.myjavalib"],
+}
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+    name: "myexports_myjavalib@current",
+    sdk_member_name: "myjavalib",
+    visibility: ["//visibility:public"],
+    apex_available: ["//apex_available:platform"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar"],
+    permitted_packages: ["pkg.myjavalib"],
+}
+
+module_exports_snapshot {
+    name: "myexports@current",
+    visibility: ["//visibility:public"],
+    java_systemserver_libs: ["myexports_myjavalib@current"],
+}
+`),
+		checkAllCopyRules(`
+.intermediates/myexports/common_os/empty -> java_systemserver_libs/snapshot/jars/are/invalid/myjavalib.jar
+`),
+	)
+}
+
 func TestHostSnapshotWithJavaImplLibrary(t *testing.T) {
 	result := android.GroupFixturePreparers(
 		prepareForSdkTestWithJava,
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
new file mode 100644
index 0000000..16e3e7f
--- /dev/null
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -0,0 +1,171 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sdk
+
+import (
+	"testing"
+
+	"android/soong/android"
+	"android/soong/dexpreopt"
+	"android/soong/java"
+)
+
+func TestSnapshotWithSystemServerClasspathFragment(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForSdkTestWithJava,
+		java.PrepareForTestWithJavaDefaultModules,
+		java.PrepareForTestWithJavaSdkLibraryFiles,
+		java.FixtureWithLastReleaseApis("mysdklibrary"),
+		dexpreopt.FixtureSetApexSystemServerJars("myapex:mylib", "myapex:mysdklibrary"),
+		prepareForSdkTestWithApex,
+
+		android.FixtureWithRootAndroidBp(`
+			sdk {
+				name: "mysdk",
+				systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+				java_sdk_libs: [
+					// This is not strictly needed as it should be automatically added to the sdk_snapshot as
+					// a java_sdk_libs module because it is used in the mysystemserverclasspathfragment's
+					// contents property. However, it is specified here to ensure that duplicates are
+					// correctly deduped.
+					"mysdklibrary",
+				],
+			}
+
+			apex {
+				name: "myapex",
+				key: "myapex.key",
+				min_sdk_version: "2",
+				systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+			}
+
+			systemserverclasspath_fragment {
+				name: "mysystemserverclasspathfragment",
+				apex_available: ["myapex"],
+				contents: [
+					"mylib",
+					"mysdklibrary",
+				],
+			}
+
+			java_library {
+				name: "mylib",
+				apex_available: ["myapex"],
+				srcs: ["Test.java"],
+				system_modules: "none",
+				sdk_version: "none",
+				min_sdk_version: "2",
+				compile_dex: true,
+				permitted_packages: ["mylib"],
+			}
+
+			java_sdk_library {
+				name: "mysdklibrary",
+				apex_available: ["myapex"],
+				srcs: ["Test.java"],
+				shared_library: false,
+				public: {enabled: true},
+				min_sdk_version: "2",
+			}
+		`),
+	).RunTest(t)
+
+	CheckSnapshot(t, result, "mysdk", "",
+		checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+    name: "mysdklibrary",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["myapex"],
+    shared_library: false,
+    public: {
+        jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+        stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+        current_api: "sdk_library/public/mysdklibrary.txt",
+        removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+        sdk_version: "current",
+    },
+}
+
+java_import {
+    name: "mylib",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["myapex"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+    permitted_packages: ["mylib"],
+}
+
+prebuilt_systemserverclasspath_fragment {
+    name: "mysystemserverclasspathfragment",
+    prefer: false,
+    visibility: ["//visibility:public"],
+    apex_available: ["myapex"],
+    contents: [
+        "mylib",
+        "mysdklibrary",
+    ],
+}
+`),
+		checkVersionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+    name: "mysdk_mysdklibrary@current",
+    sdk_member_name: "mysdklibrary",
+    visibility: ["//visibility:public"],
+    apex_available: ["myapex"],
+    shared_library: false,
+    public: {
+        jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+        stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+        current_api: "sdk_library/public/mysdklibrary.txt",
+        removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+        sdk_version: "current",
+    },
+}
+
+java_import {
+    name: "mysdk_mylib@current",
+    sdk_member_name: "mylib",
+    visibility: ["//visibility:public"],
+    apex_available: ["myapex"],
+    jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+    permitted_packages: ["mylib"],
+}
+
+prebuilt_systemserverclasspath_fragment {
+    name: "mysdk_mysystemserverclasspathfragment@current",
+    sdk_member_name: "mysystemserverclasspathfragment",
+    visibility: ["//visibility:public"],
+    apex_available: ["myapex"],
+    contents: [
+        "mysdk_mylib@current",
+        "mysdk_mysdklibrary@current",
+    ],
+}
+
+sdk_snapshot {
+    name: "mysdk@current",
+    visibility: ["//visibility:public"],
+    java_sdk_libs: ["mysdk_mysdklibrary@current"],
+    java_systemserver_libs: ["mysdk_mylib@current"],
+    systemserverclasspath_fragments: ["mysdk_mysystemserverclasspathfragment@current"],
+}
+`),
+	)
+}