Merge "No NDK libraries in clang-tidy pathDeps"
diff --git a/android/Android.bp b/android/Android.bp
index cfa2be3..a20aedc 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -113,6 +113,7 @@
         "paths_test.go",
         "prebuilt_test.go",
         "rule_builder_test.go",
+        "sdk_version_test.go",
         "sdk_test.go",
         "singleton_module_test.go",
         "soong_config_modules_test.go",
diff --git a/android/apex.go b/android/apex.go
index 6b4054d..461faf7 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -878,12 +878,8 @@
 	"kotlinx-coroutines-android-nodeps":                        30,
 	"kotlinx-coroutines-core":                                  28,
 	"kotlinx-coroutines-core-nodeps":                           30,
-	"libasyncio":                                               30,
 	"libbrotli":                                                30,
-	"libbuildversion":                                          30,
 	"libcrypto_static":                                         30,
-	"libcrypto_utils":                                          30,
-	"libdiagnose_usb":                                          30,
 	"libeigen":                                                 30,
 	"liblz4":                                                   30,
 	"libmdnssd":                                                30,
@@ -893,7 +889,6 @@
 	"libprocpartition":                                         30,
 	"libprotobuf-java-lite":                                    30,
 	"libprotoutil":                                             30,
-	"libsync":                                                  30,
 	"libtextclassifier_hash_headers":                           30,
 	"libtextclassifier_hash_static":                            30,
 	"libtflite_kernel_utils":                                   30,
diff --git a/android/api_levels.go b/android/api_levels.go
index c1b3ba2..1fbbc15 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -192,8 +192,8 @@
 // * "30" -> "30"
 // * "R" -> "30"
 // * "S" -> "S"
-func ReplaceFinalizedCodenames(ctx PathContext, raw string) string {
-	num, ok := getFinalCodenamesMap(ctx.Config())[raw]
+func ReplaceFinalizedCodenames(config Config, raw string) string {
+	num, ok := getFinalCodenamesMap(config)[raw]
 	if !ok {
 		return raw
 	}
@@ -201,7 +201,7 @@
 	return strconv.Itoa(num)
 }
 
-// Converts the given string `raw` to an ApiLevel, possibly returning an error.
+// ApiLevelFromUser converts the given string `raw` to an ApiLevel, possibly returning an error.
 //
 // `raw` must be non-empty. Passing an empty string results in a panic.
 //
@@ -216,6 +216,12 @@
 // Inputs that are not "current", known previews, or convertible to an integer
 // will return an error.
 func ApiLevelFromUser(ctx PathContext, raw string) (ApiLevel, error) {
+	return ApiLevelFromUserWithConfig(ctx.Config(), raw)
+}
+
+// ApiLevelFromUserWithConfig implements ApiLevelFromUser, see comments for
+// ApiLevelFromUser for more details.
+func ApiLevelFromUserWithConfig(config Config, raw string) (ApiLevel, error) {
 	if raw == "" {
 		panic("API level string must be non-empty")
 	}
@@ -224,13 +230,13 @@
 		return FutureApiLevel, nil
 	}
 
-	for _, preview := range ctx.Config().PreviewApiLevels() {
+	for _, preview := range config.PreviewApiLevels() {
 		if raw == preview.String() {
 			return preview, nil
 		}
 	}
 
-	canonical := ReplaceFinalizedCodenames(ctx, raw)
+	canonical := ReplaceFinalizedCodenames(config, raw)
 	asInt, err := strconv.Atoi(canonical)
 	if err != nil {
 		return NoneApiLevel, fmt.Errorf("%q could not be parsed as an integer and is not a recognized codename", canonical)
diff --git a/android/bazel.go b/android/bazel.go
index 72aad60..40c971f 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -226,34 +226,42 @@
 
 	// Configure modules in these directories to enable bp2build_available: true or false by default.
 	bp2buildDefaultConfig = Bp2BuildConfig{
-		"bionic": Bp2BuildDefaultTrueRecursively,
+		"art/libdexfile": Bp2BuildDefaultTrueRecursively,
+		"bionic":         Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/soong_config_variables":        Bp2BuildDefaultTrueRecursively,
 		"build/bazel/examples/apex/minimal":                  Bp2BuildDefaultTrueRecursively,
+		"build/soong":                                        Bp2BuildDefaultTrue,
 		"build/soong/cc/libbuildversion":                     Bp2BuildDefaultTrue, // Skip tests subdir
+		"cts/common/device-side/nativetesthelper/jni":        Bp2BuildDefaultTrueRecursively,
 		"development/sdk":                                    Bp2BuildDefaultTrueRecursively,
 		"external/arm-optimized-routines":                    Bp2BuildDefaultTrueRecursively,
 		"external/boringssl":                                 Bp2BuildDefaultTrueRecursively,
 		"external/brotli":                                    Bp2BuildDefaultTrue,
 		"external/fmtlib":                                    Bp2BuildDefaultTrueRecursively,
 		"external/google-benchmark":                          Bp2BuildDefaultTrueRecursively,
-		"external/googletest/googletest":                     Bp2BuildDefaultTrueRecursively,
+		"external/googletest":                                Bp2BuildDefaultTrueRecursively,
 		"external/gwp_asan":                                  Bp2BuildDefaultTrueRecursively,
 		"external/jemalloc_new":                              Bp2BuildDefaultTrueRecursively,
 		"external/jsoncpp":                                   Bp2BuildDefaultTrueRecursively,
 		"external/libcap":                                    Bp2BuildDefaultTrueRecursively,
 		"external/libcxx":                                    Bp2BuildDefaultTrueRecursively,
 		"external/libcxxabi":                                 Bp2BuildDefaultTrueRecursively,
+		"external/libevent":                                  Bp2BuildDefaultTrueRecursively,
 		"external/lz4/lib":                                   Bp2BuildDefaultTrue,
+		"external/lzma/C":                                    Bp2BuildDefaultTrueRecursively,
 		"external/mdnsresponder":                             Bp2BuildDefaultTrueRecursively,
 		"external/minijail":                                  Bp2BuildDefaultTrueRecursively,
 		"external/pcre":                                      Bp2BuildDefaultTrueRecursively,
 		"external/protobuf":                                  Bp2BuildDefaultTrueRecursively,
 		"external/python/six":                                Bp2BuildDefaultTrueRecursively,
+		"external/selinux/libsepol":                          Bp2BuildDefaultTrueRecursively,
 		"external/scudo":                                     Bp2BuildDefaultTrueRecursively,
 		"external/selinux/libselinux":                        Bp2BuildDefaultTrueRecursively,
 		"external/zlib":                                      Bp2BuildDefaultTrueRecursively,
 		"external/zstd":                                      Bp2BuildDefaultTrueRecursively,
 		"frameworks/native/libs/adbd_auth":                   Bp2BuildDefaultTrueRecursively,
+		"frameworks/proto_logging/stats/stats_log_api_gen":   Bp2BuildDefaultTrueRecursively,
+		"libnativehelper":                                    Bp2BuildDefaultTrueRecursively,
 		"packages/modules/adb":                               Bp2BuildDefaultTrue,
 		"packages/modules/adb/crypto":                        Bp2BuildDefaultTrueRecursively,
 		"packages/modules/adb/libs":                          Bp2BuildDefaultTrueRecursively,
@@ -263,6 +271,7 @@
 		"packages/modules/adb/tls":                           Bp2BuildDefaultTrueRecursively,
 		"prebuilts/clang/host/linux-x86":                     Bp2BuildDefaultTrueRecursively,
 		"system/apex":                                        Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures
+		"system/core/debuggerd":                              Bp2BuildDefaultTrue,
 		"system/core/diagnose_usb":                           Bp2BuildDefaultTrueRecursively,
 		"system/core/libasyncio":                             Bp2BuildDefaultTrue,
 		"system/core/libcrypto_utils":                        Bp2BuildDefaultTrueRecursively,
@@ -271,29 +280,80 @@
 		"system/core/libprocessgroup":                        Bp2BuildDefaultTrue,
 		"system/core/libprocessgroup/cgrouprc":               Bp2BuildDefaultTrue,
 		"system/core/libprocessgroup/cgrouprc_format":        Bp2BuildDefaultTrue,
+		"system/core/libsystem":                              Bp2BuildDefaultTrueRecursively,
+		"system/core/libutils":                               Bp2BuildDefaultTrueRecursively,
+		"system/core/libvndksupport":                         Bp2BuildDefaultTrueRecursively,
 		"system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively,
 		"system/libbase":                                     Bp2BuildDefaultTrueRecursively,
+		"system/libprocinfo":                                 Bp2BuildDefaultTrue,
 		"system/libziparchive":                               Bp2BuildDefaultTrueRecursively,
 		"system/logging/liblog":                              Bp2BuildDefaultTrueRecursively,
 		"system/sepolicy/apex":                               Bp2BuildDefaultTrueRecursively,
 		"system/timezone/apex":                               Bp2BuildDefaultTrueRecursively,
 		"system/timezone/output_data":                        Bp2BuildDefaultTrueRecursively,
+		"system/unwinding/libbacktrace":                      Bp2BuildDefaultTrueRecursively,
+		"system/unwinding/libunwindstack":                    Bp2BuildDefaultTrueRecursively,
 	}
 
 	// Per-module denylist to always opt modules out of both bp2build and mixed builds.
 	bp2buildModuleDoNotConvertList = []string{
+		"libnativehelper_compat_libc++",              // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
+		"art_libdexfile_dex_instruction_list_header", // breaks libart_mterp.armng, header not found
+
+		"libandroid_runtime_lazy", // depends on unconverted modules: libbinder_headers
+		"libcmd",                  // depends on unconverted modules: libbinder
+
+		"chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol
+
+		"libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules
+
+		"get_clang_version_test", // depends on unconverted module: get_clang_version
+
+		"libbinder",               // TODO(b/188503688): Disabled for some archs,
+		"libactivitymanager_aidl", // TODO(b/207426160): Depends on activity_manager_procstate_aidl, which is an aidl filegroup.
+
+		"libnativehelper_lazy_mts_jni", // depends on unconverted modules: libgmock_ndk
+		"libnativehelper_mts_jni",      // depends on unconverted modules: libgmock_ndk
+		"libnativetesthelper_jni",      // depends on unconverted modules: libgtest_ndk_c++
+
+		"statslog-framework-java-gen", "statslog.cpp", "statslog.h", "statslog.rs", "statslog_header.rs", // depends on unconverted modules: stats-log-api-gen
+
+		"stats-log-api-gen", // depends on unconverted modules: libstats_proto_host, libprotobuf-cpp-full
+
+		"libstatslog", // depends on unconverted modules: statslog.cpp, statslog.h, ...
+
+		"libgmock_main_ndk", "libgmock_ndk", // depends on unconverted module: libgtest_ndk_c++
+
+		"cmd",                                                        // depends on unconverted module packagemanager_aidl-cpp, of unsupported type aidl_interface
+		"servicedispatcher",                                          // depends on unconverted module android.debug_aidl, of unsupported type aidl_interface
+		"libutilscallstack",                                          // depends on unconverted module libbacktrace
+		"libbacktrace",                                               // depends on unconverted module libunwindstack
+		"libdebuggerd_handler",                                       // depends on unconverted module libdebuggerd_handler_core
+		"libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd
+		"unwind_for_offline",        // depends on unconverted module libunwindstack_utils
+		"libdebuggerd",              // depends on unconverted modules libdexfile_support, libunwindstack, gwp_asan_crash_handler, libtombstone_proto, libprotobuf-cpp-lite
+		"libdexfile_static",         // depends on libartpalette, libartbase, libdexfile, which are of unsupported type: art_cc_library.
+		"host_bionic_linker_asm",    // depends on extract_linker, a go binary.
+		"host_bionic_linker_script", // depends on extract_linker, a go binary.
+
+		"pbtombstone",                                  // depends on libprotobuf-cpp-lite, libtombstone_proto
+		"crash_dump",                                   // depends on unconverted module libprotobuf-cpp-lite
 		"libprotobuf-cpp-full", "libprotobuf-cpp-lite", // Unsupported product&vendor suffix. b/204811222 and b/204810610.
 
-		"libc_malloc_debug", // depends on libunwindstack, which depends on unsupported module art_cc_library_statics
+		"libunwindstack_local", "libunwindstack_utils", // depends on unconverted module libunwindstack
+		"libunwindstack",    // depends on libdexfile_support, of unsupported module type art_cc_library_static
+		"libc_malloc_debug", // depends on unconverted module libunwindstack
 
 		"libbase_ndk", // http://b/186826477, fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
 
+		"lib_linker_config_proto_lite", // contains .proto sources
+
 		"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", // 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
+		"libfdtrack",        // depends on unconverted module libunwindstack
 
 		"gwp_asan_crash_handler", // cc_library, ld.lld: error: undefined symbol: memset
 
@@ -304,10 +364,6 @@
 		"platform_tools_properties",
 		"build_tools_source_properties",
 
-		"libminijail", // b/202491296: Uses unsupported c_std property.
-		"minijail0",   // depends on unconverted modules: libminijail
-		"drop_privs",  // depends on unconverted modules: libminijail
-
 		// Tests. Handle later.
 		"libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found
 		"libjemalloc5_integrationtest",
@@ -334,14 +390,12 @@
 		"libgtest_ndk_c++",      // b/201816222: Requires sdk_version support.
 		"libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support.
 
-		"abb",                     // depends on unconverted modules: libadbd_core, libadbd_services, libcmd, libbinder, libutils, libselinux
-		"adb",                     // depends on unconverted modules: bin2c_fastdeployagent, libadb_crypto, libadb_host, libadb_pairing_connection, libadb_protos, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libmdnssd, libopenscreen-discovery, libopenscreen-platform-impl, libusb, libutils, libziparchive, libzstd, AdbWinApi
-		"adbd",                    // depends on unconverted modules: libadb_crypto, libadb_pairing_connection, libadb_protos, libadbd, libadbd_core, libapp_processes_protos_lite, libmdnssd, libzstd, libadbd_services, libcap, libminijail, libselinux
-		"bionic_tests_zipalign",   // depends on unconverted modules: libziparchive, libutils
-		"linker",                  // depends on unconverted modules: liblinker_debuggerd_stub, libdebuggerd_handler_fallback, libziparchive, liblinker_main, liblinker_malloc
+		"abb",                     // depends on unconverted modules: libadbd_core, libadbd_services,
+		"adb",                     // depends on unconverted modules: bin2c_fastdeployagent, libadb_crypto, libadb_host, libadb_pairing_connection, libadb_protos, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libopenscreen-discovery, libopenscreen-platform-impl, libusb, libzstd, AdbWinApi
+		"adbd",                    // depends on unconverted modules: libadb_crypto, libadb_pairing_connection, libadb_protos, libadbd, libadbd_core, libapp_processes_protos_lite, libzstd, libadbd_services, libcap, libminijail
+		"linker",                  // depends on unconverted modules: libdebuggerd_handler_fallback
 		"linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_*
-		"sefcontext_compile",      // depends on unconverted modules: libsepol
-		"versioner",               // depends on unconverted modules: libclang_cxx_host, libLLVM_host
+		"versioner",               // depends on unconverted modules: libclang_cxx_host, libLLVM_host, of unsupported type llvm_host_prebuilt_library_shared
 
 		"linkerconfig", // http://b/202876379 has arch-variant static_executable
 		"mdnsd",        // http://b/202876379 has arch-variant static_executable
@@ -361,8 +415,9 @@
 		"libbrotli",               // http://b/198585397, ld.lld: error: bionic/libc/arch-arm64/generic/bionic/memmove.S:95:(.text+0x10): relocation R_AARCH64_CONDBR19 out of range: -1404176 is not in [-1048576, 1048575]; references __memcpy
 		"minijail_constants_json", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
 
-		"cap_names.h", // TODO(b/204913827) runfiles need to be handled in mixed builds
-		"libcap",      // TODO(b/204913827) runfiles need to be handled in mixed builds
+		"cap_names.h",                                  // TODO(b/204913827) runfiles need to be handled in mixed builds
+		"libcap",                                       // TODO(b/204913827) runfiles need to be handled in mixed builds
+		"libprotobuf-cpp-full", "libprotobuf-cpp-lite", // Unsupported product&vendor suffix. b/204811222 and b/204810610.
 	}
 
 	// Used for quicker lookups
diff --git a/android/config.go b/android/config.go
index ed63ddf..ddad1f5 100644
--- a/android/config.go
+++ b/android/config.go
@@ -765,6 +765,16 @@
 	return levels
 }
 
+func (c *config) LatestPreviewApiLevel() ApiLevel {
+	level := NoneApiLevel
+	for _, l := range c.PreviewApiLevels() {
+		if l.GreaterThan(level) {
+			level = l
+		}
+	}
+	return level
+}
+
 func (c *config) AllSupportedApiLevels() []ApiLevel {
 	var levels []ApiLevel
 	levels = append(levels, c.FinalApiLevels()...)
diff --git a/android/module.go b/android/module.go
index 4a388b5..b500f01 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1300,6 +1300,8 @@
 
 func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {}
 
+// AddProperties "registers" the provided props
+// each value in props MUST be a pointer to a struct
 func (m *ModuleBase) AddProperties(props ...interface{}) {
 	m.registerProps = append(m.registerProps, props...)
 }
@@ -1702,7 +1704,7 @@
 }
 
 func (m *ModuleBase) InstallBypassMake() bool {
-	return false
+	return true
 }
 
 func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
diff --git a/android/mutator.go b/android/mutator.go
index 461cb17..0a93517 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -529,28 +529,6 @@
 	mod.base().addBp2buildInfo(info)
 }
 
-func (t *topDownMutatorContext) appendPrependHelper(props []interface{},
-	extendFn func([]interface{}, interface{}, proptools.ExtendPropertyFilterFunc) error) {
-	for _, p := range props {
-		err := extendFn(t.Module().base().customizableProperties, p, nil)
-		if err != nil {
-			if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
-				t.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
-			} else {
-				panic(err)
-			}
-		}
-	}
-}
-
-func (t *topDownMutatorContext) AppendProperties(props ...interface{}) {
-	t.appendPrependHelper(props, proptools.AppendMatchingProperties)
-}
-
-func (t *topDownMutatorContext) PrependProperties(props ...interface{}) {
-	t.appendPrependHelper(props, proptools.PrependMatchingProperties)
-}
-
 // android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
 // has an overridden version in android.BaseModuleContext has to be manually forwarded to BaseModuleContext to avoid
 // ambiguous method errors, or it has to store a blueprint.TopDownMutatorContext non-embedded, in which case every
diff --git a/android/sdk_version.go b/android/sdk_version.go
index 1813e7e..2004c92 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -117,7 +117,7 @@
 	return false
 }
 
-// PrebuiltSdkAvailableForUnbundledBuilt tells whether this SdkSpec can have a prebuilt SDK
+// PrebuiltSdkAvailableForUnbundledBuild tells whether this SdkSpec can have a prebuilt SDK
 // that can be used for unbundled builds.
 func (s SdkSpec) PrebuiltSdkAvailableForUnbundledBuild() bool {
 	// "", "none", and "core_platform" are not available for unbundled build
@@ -212,6 +212,10 @@
 )
 
 func SdkSpecFrom(ctx EarlyModuleContext, str string) SdkSpec {
+	return SdkSpecFromWithConfig(ctx.Config(), str)
+}
+
+func SdkSpecFromWithConfig(config Config, str string) SdkSpec {
 	switch str {
 	// special cases first
 	case "":
@@ -252,7 +256,7 @@
 			return SdkSpec{SdkInvalid, NoneApiLevel, str}
 		}
 
-		apiLevel, err := ApiLevelFromUser(ctx, versionString)
+		apiLevel, err := ApiLevelFromUserWithConfig(config, versionString)
 		if err != nil {
 			return SdkSpec{SdkInvalid, apiLevel, str}
 		}
diff --git a/android/sdk_version_test.go b/android/sdk_version_test.go
new file mode 100644
index 0000000..ec81782
--- /dev/null
+++ b/android/sdk_version_test.go
@@ -0,0 +1,89 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// 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 android
+
+import (
+	"testing"
+)
+
+func TestSdkSpecFrom(t *testing.T) {
+	testCases := []struct {
+		input    string
+		expected string
+	}{
+		{
+			input:    "",
+			expected: "private_current",
+		},
+		{
+			input:    "none",
+			expected: "none_(no version)",
+		},
+		{
+			input:    "core_platform",
+			expected: "core_platform_current",
+		},
+		{
+			input:    "_",
+			expected: "invalid_(no version)",
+		},
+		{
+			input:    "_31",
+			expected: "invalid_(no version)",
+		},
+		{
+			input:    "system_R",
+			expected: "system_30",
+		},
+		{
+			input:    "test_31",
+			expected: "test_31",
+		},
+		{
+			input:    "module_current",
+			expected: "module-lib_current",
+		},
+		{
+			input:    "31",
+			expected: "public_31",
+		},
+		{
+			input:    "S",
+			expected: "public_31",
+		},
+		{
+			input:    "current",
+			expected: "public_current",
+		},
+		{
+			input:    "Tiramisu",
+			expected: "public_Tiramisu",
+		},
+	}
+
+	config := NullConfig("", "")
+
+	config.productVariables = productVariables{
+		Platform_sdk_version:              intPtr(31),
+		Platform_sdk_codename:             stringPtr("Tiramisu"),
+		Platform_version_active_codenames: []string{"Tiramisu"},
+	}
+
+	for _, tc := range testCases {
+		if got := SdkSpecFromWithConfig(config, tc.input).String(); tc.expected != got {
+			t.Errorf("Expected %v, got %v", tc.expected, got)
+		}
+	}
+}
diff --git a/apex/apex.go b/apex/apex.go
index c1a4b40..89b5f21 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -111,6 +111,9 @@
 	// List of java libraries that are embedded inside this APEX bundle.
 	Java_libs []string
 
+	// List of sh binaries that are embedded inside this APEX bundle.
+	Sh_binaries []string
+
 	// List of platform_compat_config files that are embedded inside this APEX bundle.
 	Compat_configs []string
 
@@ -618,6 +621,7 @@
 	sharedLibTag    = dependencyTag{name: "sharedLib", payload: true}
 	testForTag      = dependencyTag{name: "test for"}
 	testTag         = dependencyTag{name: "test", payload: true}
+	shBinaryTag     = dependencyTag{name: "shBinary", payload: true}
 )
 
 // TODO(jiyong): shorten this function signature
@@ -762,6 +766,10 @@
 		for _, d := range depsList {
 			addDependenciesForNativeModules(ctx, d, target, imageVariation)
 		}
+		ctx.AddFarVariationDependencies([]blueprint.Variation{
+			{Mutator: "os", Variation: target.OsVariation()},
+			{Mutator: "arch", Variation: target.ArchVariation()},
+		}, shBinaryTag, a.properties.Sh_binaries...)
 	}
 
 	// Common-arch dependencies come next
@@ -1482,6 +1490,9 @@
 
 func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
 	dirInApex := filepath.Join("bin", sh.SubDir())
+	if sh.Target().NativeBridge == android.NativeBridgeEnabled {
+		dirInApex = filepath.Join(dirInApex, sh.Target().NativeBridgeRelativePath)
+	}
 	fileToCopy := sh.OutputFile()
 	af := newApexFile(ctx, fileToCopy, sh.BaseModuleName(), dirInApex, shBinary, sh)
 	af.symlinks = sh.Symlinks()
@@ -1710,6 +1721,7 @@
 					return true // track transitive dependencies
 				} else if r, ok := child.(*rust.Module); ok {
 					fi := apexFileForRustLibrary(ctx, r)
+					fi.isJniLib = isJniLib
 					filesInfo = append(filesInfo, fi)
 				} else {
 					propertyName := "native_shared_libs"
@@ -1722,8 +1734,6 @@
 				if cc, ok := child.(*cc.Module); ok {
 					filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc))
 					return true // track transitive dependencies
-				} else if sh, ok := child.(*sh.ShBinary); ok {
-					filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh))
 				} else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() {
 					filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py))
 				} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
@@ -1732,7 +1742,13 @@
 					filesInfo = append(filesInfo, apexFileForRustExecutable(ctx, rust))
 					return true // track transitive dependencies
 				} else {
-					ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
+					ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
+				}
+			case shBinaryTag:
+				if sh, ok := child.(*sh.ShBinary); ok {
+					filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh))
+				} else {
+					ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
 				}
 			case bcpfTag:
 				{
@@ -2361,6 +2377,9 @@
 		if a.UsePlatformApis() {
 			ctx.PropertyErrorf("updatable", "updatable APEXes can't use platform APIs")
 		}
+		if a.SocSpecific() || a.DeviceSpecific() {
+			ctx.PropertyErrorf("updatable", "vendor APEXes are not updatable")
+		}
 		a.checkJavaStableSdkVersion(ctx)
 		a.checkClasspathFragments(ctx)
 	}
@@ -3185,7 +3204,7 @@
 	File_contexts      bazel.LabelAttribute
 	Key                bazel.LabelAttribute
 	Certificate        bazel.LabelAttribute
-	Min_sdk_version    string
+	Min_sdk_version    *string
 	Updatable          bazel.BoolAttribute
 	Installable        bazel.BoolAttribute
 	Native_shared_libs bazel.LabelListAttribute
@@ -3225,9 +3244,9 @@
 		fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *module.properties.File_contexts))
 	}
 
-	var minSdkVersion string
+	var minSdkVersion *string
 	if module.properties.Min_sdk_version != nil {
-		minSdkVersion = *module.properties.Min_sdk_version
+		minSdkVersion = module.properties.Min_sdk_version
 	}
 
 	var keyLabelAttribute bazel.LabelAttribute
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 130581c..b805cd9 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4250,7 +4250,7 @@
 		apex {
 			name: "myapex",
 			key: "myapex.key",
-			binaries: ["myscript"],
+			sh_binaries: ["myscript"],
 			updatable: false,
 		}
 
@@ -7075,6 +7075,23 @@
 	`)
 }
 
+func TestUpdatable_cannot_be_vendor_apex(t *testing.T) {
+	testApexError(t, `"myapex" .*: updatable: vendor APEXes are not updatable`, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			updatable: true,
+			soc_specific: true,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+	`)
+}
+
 func TestUpdatable_should_not_set_generate_classpaths_proto(t *testing.T) {
 	testApexError(t, `"mysystemserverclasspathfragment" .* it must not set generate_classpaths_proto to false`, `
 		apex {
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index 412fa0e..d037664 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -231,3 +231,95 @@
 		`prebuilt_foo`,
 	})
 }
+
+func TestSystemserverclasspathFragmentStandaloneContents(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForTestWithSystemserverclasspathFragment,
+		prepareForTestWithMyapex,
+		dexpreopt.FixtureSetApexStandaloneSystemServerJars("myapex:foo"),
+	).RunTestWithBp(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			systemserverclasspath_fragments: [
+				"mysystemserverclasspathfragment",
+			],
+			updatable: false,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		java_library {
+			name: "foo",
+			srcs: ["b.java"],
+			installable: true,
+			apex_available: [
+				"myapex",
+			],
+		}
+
+		systemserverclasspath_fragment {
+			name: "mysystemserverclasspathfragment",
+			standalone_contents: [
+				"foo",
+			],
+			apex_available: [
+				"myapex",
+			],
+		}
+	`)
+
+	ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
+		"etc/classpaths/systemserverclasspath.pb",
+		"javalib/foo.jar",
+	})
+}
+
+func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
+	result := android.GroupFixturePreparers(
+		prepareForTestWithSystemserverclasspathFragment,
+		prepareForTestWithMyapex,
+		dexpreopt.FixtureSetApexStandaloneSystemServerJars("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,
+			standalone_contents: [
+				"foo",
+			],
+			apex_available: [
+				"myapex",
+			],
+		}
+	`)
+
+	java.CheckModuleDependencies(t, result.TestContext, "mysystemserverclasspathfragment", "android_common_myapex", []string{
+		`myapex.deapexer`,
+		`prebuilt_foo`,
+	})
+}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 10ee582..eb60cd1 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -698,9 +698,9 @@
 		} else {
 			return true
 		}
-	// Always print bools, if you want a bool attribute to be able to take the default value, use a
-	// bool pointer instead
-	case reflect.Bool:
+	// Always print bool/strings, if you want a bool/string attribute to be able to take the default value, use a
+	// pointer instead
+	case reflect.Bool, reflect.String:
 		return false
 	default:
 		if !value.IsValid() {
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 983604b..95a26a9 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -41,6 +41,7 @@
     soong_module_deps = [
     ],
     bool_prop = False,
+    string_prop = "",
 )`,
 		},
 		{
@@ -58,6 +59,7 @@
     soong_module_deps = [
     ],
     bool_prop = True,
+    string_prop = "",
 )`,
 		},
 		{
@@ -76,6 +78,7 @@
     ],
     bool_prop = False,
     owner = "a_string_with\"quotes\"_and_\\backslashes\\\\",
+    string_prop = "",
 )`,
 		},
 		{
@@ -94,6 +97,7 @@
     ],
     bool_prop = False,
     required = ["bar"],
+    string_prop = "",
 )`,
 		},
 		{
@@ -111,6 +115,7 @@
     soong_module_deps = [
     ],
     bool_prop = False,
+    string_prop = "",
     target_required = [
         "qux",
         "bazqux",
@@ -147,6 +152,7 @@
         "tag": ".bar",
         "targets": ["goal_bar"],
     }],
+    string_prop = "",
 )`,
 		},
 		{
@@ -179,6 +185,7 @@
     }],
     owner = "custom_owner",
     required = ["bar"],
+    string_prop = "",
     target_required = [
         "qux",
         "bazqux",
@@ -223,11 +230,24 @@
 func TestGenerateBazelTargetModules(t *testing.T) {
 	testCases := []bp2buildTestCase{
 		{
+			description: "string ptr props",
+			blueprint: `custom {
+	name: "foo",
+    string_ptr_prop: "",
+    bazel_module: { bp2build_available: true },
+}`,
+			expectedBazelTargets: []string{
+				makeBazelTarget("custom", "foo", attrNameToString{
+					"string_ptr_prop": `""`,
+				}),
+			},
+		},
+		{
 			description: "string props",
 			blueprint: `custom {
 	name: "foo",
     string_list_prop: ["a", "b"],
-    string_prop: "a",
+    string_ptr_prop: "a",
     bazel_module: { bp2build_available: true },
 }`,
 			expectedBazelTargets: []string{
@@ -236,7 +256,7 @@
         "a",
         "b",
     ]`,
-					"string_prop": `"a"`,
+					"string_ptr_prop": `"a"`,
 				}),
 			},
 		},
@@ -245,7 +265,7 @@
 			blueprint: `custom {
     name: "foo",
     string_list_prop: ["\t", "\n"],
-    string_prop: "a\t\n\r",
+    string_ptr_prop: "a\t\n\r",
     bazel_module: { bp2build_available: true },
 }`,
 			expectedBazelTargets: []string{
@@ -254,7 +274,7 @@
         "\t",
         "\n",
     ]`,
-					"string_prop": `"a\t\n\r"`,
+					"string_ptr_prop": `"a\t\n\r"`,
 				}),
 			},
 		},
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index a3d902a..d23ea01 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1691,8 +1691,10 @@
 func TestCcLibraryCppStdWithGnuExtensions_ConvertsToFeatureAttr(t *testing.T) {
 	type testCase struct {
 		cpp_std        string
+		c_std          string
 		gnu_extensions string
 		bazel_cpp_std  string
+		bazel_c_std    string
 	}
 
 	testCases := []testCase{
@@ -1702,45 +1704,58 @@
 		// not set, only emit if gnu_extensions is disabled. the default (gnu+17
 		// is set in the toolchain.)
 		{cpp_std: "", gnu_extensions: "", bazel_cpp_std: ""},
-		{cpp_std: "", gnu_extensions: "false", bazel_cpp_std: "c++17"},
+		{cpp_std: "", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c99"},
 		{cpp_std: "", gnu_extensions: "true", bazel_cpp_std: ""},
 		// experimental defaults to gnu++2a
 		{cpp_std: "experimental", gnu_extensions: "", bazel_cpp_std: "gnu++2a"},
-		{cpp_std: "experimental", gnu_extensions: "false", bazel_cpp_std: "c++2a"},
+		{cpp_std: "experimental", gnu_extensions: "false", bazel_cpp_std: "c++2a", bazel_c_std: "c99"},
 		{cpp_std: "experimental", gnu_extensions: "true", bazel_cpp_std: "gnu++2a"},
 		// Explicitly setting a c++ std does not use replace gnu++ std even if
 		// gnu_extensions is true.
 		// "c++11",
 		{cpp_std: "c++11", gnu_extensions: "", bazel_cpp_std: "c++11"},
-		{cpp_std: "c++11", gnu_extensions: "false", bazel_cpp_std: "c++11"},
+		{cpp_std: "c++11", gnu_extensions: "false", bazel_cpp_std: "c++11", bazel_c_std: "c99"},
 		{cpp_std: "c++11", gnu_extensions: "true", bazel_cpp_std: "c++11"},
 		// "c++17",
 		{cpp_std: "c++17", gnu_extensions: "", bazel_cpp_std: "c++17"},
-		{cpp_std: "c++17", gnu_extensions: "false", bazel_cpp_std: "c++17"},
+		{cpp_std: "c++17", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c99"},
 		{cpp_std: "c++17", gnu_extensions: "true", bazel_cpp_std: "c++17"},
 		// "c++2a",
 		{cpp_std: "c++2a", gnu_extensions: "", bazel_cpp_std: "c++2a"},
-		{cpp_std: "c++2a", gnu_extensions: "false", bazel_cpp_std: "c++2a"},
+		{cpp_std: "c++2a", gnu_extensions: "false", bazel_cpp_std: "c++2a", bazel_c_std: "c99"},
 		{cpp_std: "c++2a", gnu_extensions: "true", bazel_cpp_std: "c++2a"},
 		// "c++98",
 		{cpp_std: "c++98", gnu_extensions: "", bazel_cpp_std: "c++98"},
-		{cpp_std: "c++98", gnu_extensions: "false", bazel_cpp_std: "c++98"},
+		{cpp_std: "c++98", gnu_extensions: "false", bazel_cpp_std: "c++98", bazel_c_std: "c99"},
 		{cpp_std: "c++98", gnu_extensions: "true", bazel_cpp_std: "c++98"},
 		// gnu++ is replaced with c++ if gnu_extensions is explicitly false.
 		// "gnu++11",
 		{cpp_std: "gnu++11", gnu_extensions: "", bazel_cpp_std: "gnu++11"},
-		{cpp_std: "gnu++11", gnu_extensions: "false", bazel_cpp_std: "c++11"},
+		{cpp_std: "gnu++11", gnu_extensions: "false", bazel_cpp_std: "c++11", bazel_c_std: "c99"},
 		{cpp_std: "gnu++11", gnu_extensions: "true", bazel_cpp_std: "gnu++11"},
 		// "gnu++17",
 		{cpp_std: "gnu++17", gnu_extensions: "", bazel_cpp_std: "gnu++17"},
-		{cpp_std: "gnu++17", gnu_extensions: "false", bazel_cpp_std: "c++17"},
+		{cpp_std: "gnu++17", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c99"},
 		{cpp_std: "gnu++17", gnu_extensions: "true", bazel_cpp_std: "gnu++17"},
+
+		// some c_std test cases
+		{c_std: "experimental", gnu_extensions: "", bazel_c_std: "gnu11"},
+		{c_std: "experimental", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c11"},
+		{c_std: "experimental", gnu_extensions: "true", bazel_c_std: "gnu11"},
+		{c_std: "gnu11", cpp_std: "gnu++17", gnu_extensions: "", bazel_cpp_std: "gnu++17", bazel_c_std: "gnu11"},
+		{c_std: "gnu11", cpp_std: "gnu++17", gnu_extensions: "false", bazel_cpp_std: "c++17", bazel_c_std: "c11"},
+		{c_std: "gnu11", cpp_std: "gnu++17", gnu_extensions: "true", bazel_cpp_std: "gnu++17", bazel_c_std: "gnu11"},
 	}
-	for _, tc := range testCases {
+	for i, tc := range testCases {
+		name_prefix := fmt.Sprintf("a_%v", i)
 		cppStdProp := ""
 		if tc.cpp_std != "" {
 			cppStdProp = fmt.Sprintf("    cpp_std: \"%s\",", tc.cpp_std)
 		}
+		cStdProp := ""
+		if tc.c_std != "" {
+			cStdProp = fmt.Sprintf("    c_std: \"%s\",", tc.c_std)
+		}
 		gnuExtensionsProp := ""
 		if tc.gnu_extensions != "" {
 			gnuExtensionsProp = fmt.Sprintf("    gnu_extensions: %s,", tc.gnu_extensions)
@@ -1749,61 +1764,67 @@
 		if tc.bazel_cpp_std != "" {
 			attrs["cpp_std"] = fmt.Sprintf(`"%s"`, tc.bazel_cpp_std)
 		}
+		if tc.bazel_c_std != "" {
+			attrs["c_std"] = fmt.Sprintf(`"%s"`, tc.bazel_c_std)
+		}
 
 		runCcLibraryTestCase(t, bp2buildTestCase{
 			description: fmt.Sprintf(
-				"cc_library with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
+				"cc_library with c_std: %s, cpp_std: %s and gnu_extensions: %s", tc.c_std, tc.cpp_std, tc.gnu_extensions),
 			moduleTypeUnderTest:                "cc_library",
 			moduleTypeUnderTestFactory:         cc.LibraryFactory,
 			moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
 			blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
 cc_library {
-	name: "a",
+	name: "%s_full",
 %s // cpp_std: *string
+%s // c_std: *string
 %s // gnu_extensions: *bool
 	include_build_directory: false,
 }
-`, cppStdProp, gnuExtensionsProp),
+`, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
 			expectedBazelTargets: []string{
-				makeBazelTarget("cc_library", "a", attrs),
+				makeBazelTarget("cc_library", name_prefix+"_full", attrs),
 			},
 		})
 
 		runCcLibraryStaticTestCase(t, bp2buildTestCase{
 			description: fmt.Sprintf(
-				"cc_library_static with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
+				"cc_library_static with c_std: %s, cpp_std: %s and gnu_extensions: %s", tc.c_std, tc.cpp_std, tc.gnu_extensions),
 			moduleTypeUnderTest:                "cc_library_static",
 			moduleTypeUnderTestFactory:         cc.LibraryStaticFactory,
 			moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
 			blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
 cc_library_static {
-	name: "a",
+	name: "%s_static",
 %s // cpp_std: *string
+%s // c_std: *string
 %s // gnu_extensions: *bool
 	include_build_directory: false,
 }
-`, cppStdProp, gnuExtensionsProp),
+`, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
 			expectedBazelTargets: []string{
-				makeBazelTarget("cc_library_static", "a", attrs),
+				makeBazelTarget("cc_library_static", name_prefix+"_static", attrs),
 			},
 		})
 
 		runCcLibrarySharedTestCase(t, bp2buildTestCase{
 			description: fmt.Sprintf(
-				"cc_library_shared with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions),
+				"cc_library_shared with c_std: %s, cpp_std: %s and gnu_extensions: %s", tc.c_std, tc.cpp_std, tc.gnu_extensions),
 			moduleTypeUnderTest:                "cc_library_shared",
 			moduleTypeUnderTestFactory:         cc.LibrarySharedFactory,
 			moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build,
 			blueprint: soongCcLibraryPreamble + fmt.Sprintf(`
 cc_library_shared {
-	name: "a",
+	name: "%s_shared",
 %s // cpp_std: *string
+%s // c_std: *string
 %s // gnu_extensions: *bool
 	include_build_directory: false,
 }
-`, cppStdProp, gnuExtensionsProp),
+`, name_prefix, cppStdProp, cStdProp, gnuExtensionsProp),
 			expectedBazelTargets: []string{
-				makeBazelTarget("cc_library_shared", "a", attrs),
+				makeBazelTarget("cc_library_shared", name_prefix+"_shared", attrs),
 			},
 		})
 	}
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index 1ca4a0e..0d87c8d 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -62,11 +62,15 @@
 		blueprint: `sh_binary {
     name: "foo",
     src: "foo.sh",
+    filename: "foo.exe",
+    sub_dir: "sub",
     bazel_module: { bp2build_available: true },
 }`,
 		expectedBazelTargets: []string{
 			makeBazelTarget("sh_binary", "foo", attrNameToString{
-				"srcs": `["foo.sh"]`,
+				"srcs":     `["foo.sh"]`,
+				"filename": `"foo.exe"`,
+				"sub_dir":  `"sub"`,
 			})},
 	})
 }
diff --git a/bp2build/testing.go b/bp2build/testing.go
index daa9c22..cd84519 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -149,15 +149,15 @@
 }
 
 type nestedProps struct {
-	Nested_prop string
+	Nested_prop *string
 }
 
 type EmbeddedProps struct {
-	Embedded_prop string
+	Embedded_prop *string
 }
 
 type OtherEmbeddedProps struct {
-	Other_embedded_prop string
+	Other_embedded_prop *string
 }
 
 type customProps struct {
@@ -262,17 +262,17 @@
 }
 
 type EmbeddedAttr struct {
-	Embedded_attr string
+	Embedded_attr *string
 }
 
 type OtherEmbeddedAttr struct {
-	Other_embedded_attr string
+	Other_embedded_attr *string
 }
 
 type customBazelModuleAttributes struct {
 	EmbeddedAttr
 	*OtherEmbeddedAttr
-	String_prop      string
+	String_ptr_prop  *string
 	String_list_prop []string
 	Arch_paths       bazel.LabelListAttribute
 }
@@ -296,7 +296,7 @@
 		paths.ResolveExcludes()
 
 		attrs := &customBazelModuleAttributes{
-			String_prop:      m.props.String_prop,
+			String_ptr_prop:  m.props.String_ptr_prop,
 			String_list_prop: m.props.String_list_prop,
 			Arch_paths:       paths,
 		}
diff --git a/build_test.bash b/build_test.bash
index b039285..b6d00e2 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -50,7 +50,9 @@
 
 echo
 echo "Free disk space:"
-df -h
+# Ignore df errors because it errors out on gvfsd file systems
+# but still displays most of the useful info we need
+df -h || true
 
 echo
 echo "Running Bazel smoke test..."
diff --git a/cc/bp2build.go b/cc/bp2build.go
index d949436..888c3ba 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -252,6 +252,7 @@
 
 	// Not affected by arch variants
 	stl    *string
+	cStd   *string
 	cppStd *string
 
 	localIncludes    bazel.StringListAttribute
@@ -278,8 +279,7 @@
 
 	localIncludeDirs := props.Local_include_dirs
 	if axis == bazel.NoConfigAxis {
-		ca.cppStd = bp2buildResolveCppStdValue(props.Cpp_std, props.Gnu_extensions)
-
+		ca.cStd, ca.cppStd = bp2buildResolveCppStdValue(props.C_std, props.Cpp_std, props.Gnu_extensions)
 		if includeBuildDirectory(props.Include_build_directory) {
 			localIncludeDirs = append(localIncludeDirs, ".")
 		}
@@ -371,24 +371,32 @@
 	return bazel.AppendBazelLabelLists(allSrcsLabelList, generatedSrcsLabelList), anySrcs
 }
 
-func bp2buildResolveCppStdValue(cpp_std *string, gnu_extensions *bool) *string {
-	var cppStd *string
-	// If cpp_std is not specified, don't generate it in the
-	// BUILD file. For readability purposes, cpp_std and gnu_extensions are
-	// combined into a single -std=<version> copt, except in the
-	// default case where cpp_std is nil and gnu_extensions is true or unspecified,
-	// then the toolchain's default "gnu++17" will be used.
+func bp2buildResolveCppStdValue(c_std *string, cpp_std *string, gnu_extensions *bool) (*string, *string) {
+	var cStdVal, cppStdVal string
+	// If c{,pp}std properties are not specified, don't generate them in the BUILD file.
+	// Defaults are handled by the toolchain definition.
+	// However, if gnu_extensions is false, then the default gnu-to-c version must be specified.
 	if cpp_std != nil {
-		// TODO(b/202491296): Handle C_std.
-		// These transformations are shared with compiler.go.
-		cppStdVal := parseCppStd(cpp_std)
-		_, cppStdVal = maybeReplaceGnuToC(gnu_extensions, "", cppStdVal)
-		cppStd = &cppStdVal
+		cppStdVal = parseCppStd(cpp_std)
 	} else if gnu_extensions != nil && !*gnu_extensions {
-		cppStdVal := "c++17"
-		cppStd = &cppStdVal
+		cppStdVal = "c++17"
 	}
-	return cppStd
+	if c_std != nil {
+		cStdVal = parseCStd(c_std)
+	} else if gnu_extensions != nil && !*gnu_extensions {
+		cStdVal = "c99"
+	}
+
+	cStdVal, cppStdVal = maybeReplaceGnuToC(gnu_extensions, cStdVal, cppStdVal)
+	var c_std_prop, cpp_std_prop *string
+	if cStdVal != "" {
+		c_std_prop = &cStdVal
+	}
+	if cppStdVal != "" {
+		cpp_std_prop = &cppStdVal
+	}
+
+	return c_std_prop, cpp_std_prop
 }
 
 // bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
diff --git a/cc/compiler.go b/cc/compiler.go
index ffe8b2e..2e62b00 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -304,11 +304,24 @@
 	cppStd := String(cppStdPtr)
 	switch cppStd {
 	case "":
-		cppStd = config.CppStdVersion
+		return config.CppStdVersion
 	case "experimental":
-		cppStd = config.ExperimentalCppStdVersion
+		return config.ExperimentalCppStdVersion
+	default:
+		return cppStd
 	}
-	return cppStd
+}
+
+func parseCStd(cStdPtr *string) string {
+	cStd := String(cStdPtr)
+	switch cStd {
+	case "":
+		return config.CStdVersion
+	case "experimental":
+		return config.ExperimentalCStdVersion
+	default:
+		return cStd
+	}
 }
 
 // Create a Flags struct that collects the compile flags from global values,
@@ -479,13 +492,7 @@
 
 	flags.Global.CommonFlags = append(flags.Global.CommonFlags, tc.ToolchainCflags())
 
-	cStd := config.CStdVersion
-	if String(compiler.Properties.C_std) == "experimental" {
-		cStd = config.ExperimentalCStdVersion
-	} else if String(compiler.Properties.C_std) != "" {
-		cStd = String(compiler.Properties.C_std)
-	}
-
+	cStd := parseCStd(compiler.Properties.C_std)
 	cppStd := parseCppStd(compiler.Properties.Cpp_std)
 
 	cStd, cppStd = maybeReplaceGnuToC(compiler.Properties.Gnu_extensions, cStd, cppStd)
diff --git a/cc/libbuildversion/Android.bp b/cc/libbuildversion/Android.bp
index 4debb1c..2cff994 100644
--- a/cc/libbuildversion/Android.bp
+++ b/cc/libbuildversion/Android.bp
@@ -14,6 +14,7 @@
             enabled: true,
         },
     },
+    min_sdk_version: "26",
     apex_available: [
         "//apex_available:platform",
         "//apex_available:anyapex",
diff --git a/cc/library.go b/cc/library.go
index dbf927d..3dceda0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -253,6 +253,7 @@
 
 	Stl     *string
 	Cpp_std *string
+	C_std   *string
 
 	// This is shared only.
 	Link_crt                 bazel.BoolAttribute
@@ -335,6 +336,7 @@
 		Rtti:                        compilerAttrs.rtti,
 		Stl:                         compilerAttrs.stl,
 		Cpp_std:                     compilerAttrs.cppStd,
+		C_std:                       compilerAttrs.cStd,
 
 		Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
 
@@ -2420,6 +2422,7 @@
 			Rtti:                   compilerAttrs.rtti,
 			Stl:                    compilerAttrs.stl,
 			Cpp_std:                compilerAttrs.cppStd,
+			C_std:                  compilerAttrs.cStd,
 			Export_includes:        exportedIncludes.Includes,
 			Export_system_includes: exportedIncludes.SystemIncludes,
 			Local_includes:         compilerAttrs.localIncludes,
@@ -2445,6 +2448,7 @@
 			Rtti:       compilerAttrs.rtti,
 			Stl:        compilerAttrs.stl,
 			Cpp_std:    compilerAttrs.cppStd,
+			C_std:      compilerAttrs.cStd,
 
 			Export_includes:          exportedIncludes.Includes,
 			Export_system_includes:   exportedIncludes.SystemIncludes,
@@ -2480,6 +2484,7 @@
 	Rtti       bazel.BoolAttribute
 	Stl        *string
 	Cpp_std    *string
+	C_std      *string
 
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
@@ -2516,6 +2521,7 @@
 	Rtti       bazel.BoolAttribute
 	Stl        *string
 	Cpp_std    *string
+	C_std      *string
 
 	Export_includes        bazel.StringListAttribute
 	Export_system_includes bazel.StringListAttribute
diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go
index 9789ab0..3e448ba 100644
--- a/cc/library_headers_test.go
+++ b/cc/library_headers_test.go
@@ -16,7 +16,6 @@
 
 import (
 	"fmt"
-	"strings"
 	"testing"
 
 	"android/soong/android"
@@ -25,44 +24,37 @@
 )
 
 func TestLibraryHeaders(t *testing.T) {
-	ctx := testCc(t, `
-	cc_library_headers {
-		name: "headers",
-		export_include_dirs: ["my_include"],
-	}
-	cc_library_static {
-		name: "lib",
-		srcs: ["foo.c"],
-		header_libs: ["headers"],
-	}
-	`)
+	bp := `
+		%s {
+			name: "headers",
+			export_include_dirs: ["my_include"],
+		}
+		cc_library_static {
+			name: "lib",
+			srcs: ["foo.c"],
+			header_libs: ["headers"],
+		}
+	`
 
-	// test if header search paths are correctly added
-	cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc")
-	cflags := cc.Args["cFlags"]
-	if !strings.Contains(cflags, " -Imy_include ") {
-		t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
-	}
-}
+	for _, headerModule := range []string{"cc_library_headers", "cc_prebuilt_library_headers"} {
+		t.Run(headerModule, func(t *testing.T) {
+			ctx := testCc(t, fmt.Sprintf(bp, headerModule))
 
-func TestPrebuiltLibraryHeaders(t *testing.T) {
-	ctx := testCc(t, `
-	cc_prebuilt_library_headers {
-		name: "headers",
-		export_include_dirs: ["my_include"],
-	}
-	cc_library_static {
-		name: "lib",
-		srcs: ["foo.c"],
-		header_libs: ["headers"],
-	}
-	`)
+			// test if header search paths are correctly added
+			cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc")
+			android.AssertStringDoesContain(t, "cFlags for lib module", cc.Args["cFlags"], " -Imy_include ")
 
-	// test if header search paths are correctly added
-	cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc")
-	cflags := cc.Args["cFlags"]
-	if !strings.Contains(cflags, " -Imy_include ") {
-		t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
+			// Test that there's a valid AndroidMk entry.
+			headers := ctx.ModuleForTests("headers", "android_arm64_armv8-a").Module()
+			e := android.AndroidMkEntriesForTest(t, ctx, headers)[0]
+
+			// This duplicates the tests done in AndroidMkEntries.write. It would be
+			// better to test its output, but there are no test functions that capture that.
+			android.AssertBoolEquals(t, "AndroidMkEntries.Disabled", false, e.Disabled)
+			android.AssertBoolEquals(t, "AndroidMkEntries.OutputFile.Valid()", true, e.OutputFile.Valid())
+
+			android.AssertStringListContains(t, "LOCAL_EXPORT_CFLAGS for headers module", e.EntryMap["LOCAL_EXPORT_CFLAGS"], "-Imy_include")
+		})
 	}
 }
 
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index a279054..c303fda 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -197,7 +197,13 @@
 	if p.header() {
 		ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{})
 
-		return nil
+		// Need to return an output path so that the AndroidMk logic doesn't skip
+		// the prebuilt header. For compatibility, in case Android.mk files use a
+		// header lib in LOCAL_STATIC_LIBRARIES, create an empty ar file as
+		// placeholder, just like non-prebuilt header modules do in linkStatic().
+		ph := android.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
+		transformObjToStaticLib(ctx, nil, nil, builderFlags{}, ph, nil, nil)
+		return ph
 	}
 
 	return nil
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index dfc4eae..c81d4bc 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -386,7 +386,7 @@
 // - won't be overwritten by corresponding bp2build generated files
 //
 // And return their paths so they can be left out of the Bazel workspace dir (i.e. ignored)
-func getPathsToIgnoredBuildFiles(topDir string, generatedRoot string, srcDirBazelFiles []string) []string {
+func getPathsToIgnoredBuildFiles(topDir string, generatedRoot string, srcDirBazelFiles []string, verbose bool) []string {
 	paths := make([]string, 0)
 
 	for _, srcDirBazelFileRelativePath := range srcDirBazelFiles {
@@ -416,7 +416,9 @@
 			// BUILD file clash resolution happens later in the symlink forest creation
 			continue
 		}
-		fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
+		if verbose {
+			fmt.Fprintf(os.Stderr, "Ignoring existing BUILD file: %s\n", srcDirBazelFileRelativePath)
+		}
 		paths = append(paths, srcDirBazelFileRelativePath)
 	}
 
@@ -523,7 +525,7 @@
 		os.Exit(1)
 	}
 
-	pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(topDir, generatedRoot, existingBazelRelatedFiles)
+	pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(topDir, generatedRoot, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
 	excludes = append(excludes, pathsToIgnoredBuildFiles...)
 
 	excludes = append(excludes, getTemporaryExcludes()...)
diff --git a/compliance/build_license_metadata/Android.bp b/compliance/build_license_metadata/Android.bp
index 5000346..4826526 100644
--- a/compliance/build_license_metadata/Android.bp
+++ b/compliance/build_license_metadata/Android.bp
@@ -25,5 +25,6 @@
         "license_metadata_proto",
         "golang-protobuf-proto",
         "golang-protobuf-encoding-prototext",
+        "soong-response",
     ],
 }
diff --git a/compliance/build_license_metadata/build_license_metadata.go b/compliance/build_license_metadata/build_license_metadata.go
index 8b1fe58..53d2407 100644
--- a/compliance/build_license_metadata/build_license_metadata.go
+++ b/compliance/build_license_metadata/build_license_metadata.go
@@ -26,28 +26,12 @@
 	"google.golang.org/protobuf/proto"
 
 	"android/soong/compliance/license_metadata_proto"
+	"android/soong/response"
 )
 
-var (
-	packageName  = flag.String("p", "", "license package name")
-	moduleType   = newMultiString("mt", "module type")
-	moduleClass  = newMultiString("mc", "module class")
-	kinds        = newMultiString("k", "license kinds")
-	conditions   = newMultiString("c", "license conditions")
-	notices      = newMultiString("n", "license notice file")
-	deps         = newMultiString("d", "license metadata file dependency")
-	sources      = newMultiString("s", "source (input) dependency")
-	built        = newMultiString("t", "built targets")
-	installed    = newMultiString("i", "installed targets")
-	roots        = newMultiString("r", "root directory of project")
-	installedMap = newMultiString("m", "map dependent targets to their installed names")
-	isContainer  = flag.Bool("is_container", false, "preserved dependent target name when given")
-	outFile      = flag.String("o", "", "output file")
-)
-
-func newMultiString(name, usage string) *multiString {
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
 	var f multiString
-	flag.Var(&f, name, usage)
+	flags.Var(&f, name, usage)
 	return &f
 }
 
@@ -57,7 +41,45 @@
 func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
 
 func main() {
-	flag.Parse()
+	var expandedArgs []string
+	for _, arg := range os.Args[1:] {
+		if strings.HasPrefix(arg, "@") {
+			f, err := os.Open(strings.TrimPrefix(arg, "@"))
+			if err != nil {
+				fmt.Fprintln(os.Stderr, err.Error())
+				os.Exit(1)
+			}
+
+			respArgs, err := response.ReadRspFile(f)
+			f.Close()
+			if err != nil {
+				fmt.Fprintln(os.Stderr, err.Error())
+				os.Exit(1)
+			}
+			expandedArgs = append(expandedArgs, respArgs...)
+		} else {
+			expandedArgs = append(expandedArgs, arg)
+		}
+	}
+
+	flags := flag.NewFlagSet("flags", flag.ExitOnError)
+
+	packageName := flags.String("p", "", "license package name")
+	moduleType := newMultiString(flags, "mt", "module type")
+	kinds := newMultiString(flags, "k", "license kinds")
+	moduleClass := newMultiString(flags, "mc", "module class")
+	conditions := newMultiString(flags, "c", "license conditions")
+	notices := newMultiString(flags, "n", "license notice file")
+	deps := newMultiString(flags, "d", "license metadata file dependency")
+	sources := newMultiString(flags, "s", "source (input) dependency")
+	built := newMultiString(flags, "t", "built targets")
+	installed := newMultiString(flags, "i", "installed targets")
+	roots := newMultiString(flags, "r", "root directory of project")
+	installedMap := newMultiString(flags, "m", "map dependent targets to their installed names")
+	isContainer := flags.Bool("is_container", false, "preserved dependent target name when given")
+	outFile := flags.String("o", "", "output file")
+
+	flags.Parse(expandedArgs)
 
 	metadata := license_metadata_proto.LicenseMetadata{}
 	metadata.PackageName = proto.String(*packageName)
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index de3666a..6d6b41d 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -49,10 +49,12 @@
 
 	ArtApexJars android.ConfiguredJarList // modules for jars that are in the ART APEX
 
-	SystemServerJars     android.ConfiguredJarList // jars that form the system server
-	SystemServerApps     []string                  // apps that are loaded into system server
-	ApexSystemServerJars android.ConfiguredJarList // jars within apex that are loaded into system server
-	SpeedApps            []string                  // apps that should be speed optimized
+	SystemServerJars               android.ConfiguredJarList // system_server classpath jars on the platform
+	SystemServerApps               []string                  // apps that are loaded into system server
+	ApexSystemServerJars           android.ConfiguredJarList // system_server classpath jars delivered via apex
+	StandaloneSystemServerJars     android.ConfiguredJarList // jars on the platform that system_server loads dynamically using separate classloaders
+	ApexStandaloneSystemServerJars android.ConfiguredJarList // jars delivered via apex that system_server loads dynamically using separate classloaders
+	SpeedApps                      []string                  // apps that should be speed optimized
 
 	BrokenSuboptimalOrderOfSystemServerJars bool // if true, sub-optimal order does not cause a build error
 
@@ -619,6 +621,8 @@
 		SystemServerJars:                   android.EmptyConfiguredJarList(),
 		SystemServerApps:                   nil,
 		ApexSystemServerJars:               android.EmptyConfiguredJarList(),
+		StandaloneSystemServerJars:         android.EmptyConfiguredJarList(),
+		ApexStandaloneSystemServerJars:     android.EmptyConfiguredJarList(),
 		SpeedApps:                          nil,
 		PreoptFlags:                        nil,
 		DefaultCompilerFilter:              "",
diff --git a/dexpreopt/testing.go b/dexpreopt/testing.go
index 8f5c315..2fba01a 100644
--- a/dexpreopt/testing.go
+++ b/dexpreopt/testing.go
@@ -125,6 +125,13 @@
 	})
 }
 
+// FixtureSetStandaloneSystemServerJars sets the StandaloneSystemServerJars property.
+func FixtureSetStandaloneSystemServerJars(jars ...string) android.FixturePreparer {
+	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+		dexpreoptConfig.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(jars)
+	})
+}
+
 // FixtureSetSystemServerJars sets the SystemServerJars property.
 func FixtureSetSystemServerJars(jars ...string) android.FixturePreparer {
 	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
@@ -139,6 +146,14 @@
 	})
 }
 
+// FixtureSetApexStandaloneSystemServerJars sets the ApexStandaloneSystemServerJars property in the
+// global config.
+func FixtureSetApexStandaloneSystemServerJars(jars ...string) android.FixturePreparer {
+	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
+		dexpreoptConfig.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(jars)
+	})
+}
+
 // FixtureSetPreoptWithUpdatableBcp sets the PreoptWithUpdatableBcp property in the global config.
 func FixtureSetPreoptWithUpdatableBcp(value bool) android.FixturePreparer {
 	return FixtureModifyGlobalConfig(func(dexpreoptConfig *GlobalConfig) {
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 38065f1..3a1f5fc 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"strconv"
 	"strings"
 
 	"github.com/google/blueprint"
@@ -42,6 +43,20 @@
 	},
 	"args", "libs")
 
+// targetSdkVersion for manifest_fixer
+// When TARGET_BUILD_APPS is not empty, this method returns the unreleased(future) API level
+// This enables release builds (that run with TARGET_BUILD_APPS=[val...]) to target APIs that have not yet been finalized as part of an SDK
+func targetSdkVersionForManifestFixer(ctx android.ModuleContext, sdkContext android.SdkContext) string {
+	if ctx.Config().UnbundledBuildApps() {
+		return strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt())
+	}
+	targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx)
+	if err != nil {
+		ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
+	}
+	return targetSdkVersion
+}
+
 // Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
 func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext android.SdkContext,
 	classLoaderContexts dexpreopt.ClassLoaderContextMap, isLibrary, useEmbeddedNativeLibs, usesNonSdkApis,
@@ -89,10 +104,7 @@
 		args = append(args, "--logging-parent", loggingParent)
 	}
 	var deps android.Paths
-	targetSdkVersion, err := sdkContext.TargetSdkVersion(ctx).EffectiveVersionString(ctx)
-	if err != nil {
-		ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
-	}
+	targetSdkVersion := targetSdkVersionForManifestFixer(ctx, sdkContext)
 	if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
 		targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
 		deps = append(deps, ApiFingerprintPath(ctx))
diff --git a/java/base.go b/java/base.go
index d9b1260..2f90db2 100644
--- a/java/base.go
+++ b/java/base.go
@@ -197,6 +197,10 @@
 	// Defaults to sdk_version if not set. See sdk_version for possible values.
 	Min_sdk_version *string
 
+	// if not blank, set the maximum version of the sdk that the compiled artifacts will run against.
+	// Defaults to empty string "". See sdk_version for possible values.
+	Max_sdk_version *string
+
 	// if not blank, set the targetSdkVersion in the AndroidManifest.xml.
 	// Defaults to sdk_version if not set. See sdk_version for possible values.
 	Target_sdk_version *string
@@ -460,6 +464,7 @@
 
 	sdkVersion    android.SdkSpec
 	minSdkVersion android.SdkSpec
+	maxSdkVersion android.SdkSpec
 }
 
 func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -617,6 +622,13 @@
 	return j.SdkVersion(ctx)
 }
 
+func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
+	maxSdkVersion := proptools.StringDefault(j.deviceProperties.Max_sdk_version, "")
+	// SdkSpecFrom returns SdkSpecPrivate for this, which may be confusing.
+	// TODO(b/208456999): ideally MaxSdkVersion should be an ApiLevel and not SdkSpec.
+	return android.SdkSpecFrom(ctx, maxSdkVersion)
+}
+
 func (j *Module) MinSdkVersionString() string {
 	return j.minSdkVersion.Raw
 }
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index f63d81d..e77971b 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -25,7 +25,7 @@
 	"android/soong/android"
 )
 
-// Build rules and utilities to generate individual packages/modules/SdkExtensions/proto/classpaths.proto
+// Build rules and utilities to generate individual packages/modules/common/proto/classpaths.proto
 // config files based on build configuration to embed into /system and /apex on a device.
 //
 // See `derive_classpath` service that reads the configs at runtime and defines *CLASSPATH variables
@@ -34,14 +34,15 @@
 type classpathType int
 
 const (
-	// Matches definition in packages/modules/SdkExtensions/proto/classpaths.proto
+	// Matches definition in packages/modules/common/proto/classpaths.proto
 	BOOTCLASSPATH classpathType = iota
 	DEX2OATBOOTCLASSPATH
 	SYSTEMSERVERCLASSPATH
+	STANDALONE_SYSTEMSERVER_JARS
 )
 
 func (c classpathType) String() string {
-	return [...]string{"BOOTCLASSPATH", "DEX2OATBOOTCLASSPATH", "SYSTEMSERVERCLASSPATH"}[c]
+	return [...]string{"BOOTCLASSPATH", "DEX2OATBOOTCLASSPATH", "SYSTEMSERVERCLASSPATH", "STANDALONE_SYSTEMSERVER_JARS"}[c]
 }
 
 type classpathFragmentProperties struct {
@@ -84,11 +85,10 @@
 
 // Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto
 type classpathJar struct {
-	path      string
-	classpath classpathType
-	// TODO(satayev): propagate min/max sdk versions for the jars
-	minSdkVersion int32
-	maxSdkVersion int32
+	path          string
+	classpath     classpathType
+	minSdkVersion string
+	maxSdkVersion string
 }
 
 // gatherPossibleApexModuleNamesAndStems returns a set of module and stem names from the
@@ -120,10 +120,32 @@
 	jars := make([]classpathJar, 0, len(paths)*len(classpaths))
 	for i := 0; i < len(paths); i++ {
 		for _, classpathType := range classpaths {
-			jars = append(jars, classpathJar{
+			jar := classpathJar{
 				classpath: classpathType,
 				path:      paths[i],
+			}
+			ctx.VisitDirectDepsIf(func(m android.Module) bool {
+				return m.Name() == configuredJars.Jar(i)
+			}, func(m android.Module) {
+				if s, ok := m.(*SdkLibrary); ok {
+					// TODO(208456999): instead of mapping "current" to latest, min_sdk_version should never be set to "current"
+					if s.minSdkVersion.Specified() {
+						if s.minSdkVersion.ApiLevel.IsCurrent() {
+							jar.minSdkVersion = ctx.Config().LatestPreviewApiLevel().String()
+						} else {
+							jar.minSdkVersion = s.minSdkVersion.ApiLevel.String()
+						}
+					}
+					if s.maxSdkVersion.Specified() {
+						if s.maxSdkVersion.ApiLevel.IsCurrent() {
+							jar.maxSdkVersion = ctx.Config().LatestPreviewApiLevel().String()
+						} else {
+							jar.maxSdkVersion = s.maxSdkVersion.ApiLevel.String()
+						}
+					}
+				}
 			})
+			jars = append(jars, jar)
 		}
 	}
 	return jars
@@ -136,15 +158,15 @@
 		c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
 		c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")
 
-		generatedJson := android.PathForModuleOut(ctx, outputFilename+".json")
-		writeClasspathsJson(ctx, generatedJson, jars)
+		generatedTextproto := android.PathForModuleOut(ctx, outputFilename+".textproto")
+		writeClasspathsTextproto(ctx, generatedTextproto, jars)
 
 		rule := android.NewRuleBuilder(pctx, ctx)
 		rule.Command().
 			BuiltTool("conv_classpaths_proto").
 			Flag("encode").
-			Flag("--format=json").
-			FlagWithInput("--input=", generatedJson).
+			Flag("--format=textproto").
+			FlagWithInput("--input=", generatedTextproto).
 			FlagWithOutput("--output=", c.outputFilepath)
 
 		rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String())
@@ -159,24 +181,18 @@
 	ctx.SetProvider(ClasspathFragmentProtoContentInfoProvider, classpathProtoInfo)
 }
 
-func writeClasspathsJson(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
+func writeClasspathsTextproto(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
 	var content strings.Builder
-	fmt.Fprintf(&content, "{\n")
-	fmt.Fprintf(&content, "\"jars\": [\n")
-	for idx, jar := range jars {
-		fmt.Fprintf(&content, "{\n")
 
-		fmt.Fprintf(&content, "\"path\": \"%s\",\n", jar.path)
-		fmt.Fprintf(&content, "\"classpath\": \"%s\"\n", jar.classpath)
-
-		if idx < len(jars)-1 {
-			fmt.Fprintf(&content, "},\n")
-		} else {
-			fmt.Fprintf(&content, "}\n")
-		}
+	for _, jar := range jars {
+		fmt.Fprintf(&content, "jars {\n")
+		fmt.Fprintf(&content, "path: \"%s\"\n", jar.path)
+		fmt.Fprintf(&content, "classpath: %s\n", jar.classpath)
+		fmt.Fprintf(&content, "min_sdk_version: \"%s\"\n", jar.minSdkVersion)
+		fmt.Fprintf(&content, "max_sdk_version: \"%s\"\n", jar.maxSdkVersion)
+		fmt.Fprintf(&content, "}\n")
 	}
-	fmt.Fprintf(&content, "]\n")
-	fmt.Fprintf(&content, "}\n")
+
 	android.WriteFileRule(ctx, output, content.String())
 }
 
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 7c081b6..f3a53ee 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -122,13 +122,7 @@
 }
 
 func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
-	global := dexpreopt.GetGlobalConfig(ctx)
-
-	if global.DisablePreopt {
-		return true
-	}
-
-	if inList(moduleName(ctx), global.DisablePreoptModules) {
+	if !ctx.Device() {
 		return true
 	}
 
@@ -144,7 +138,17 @@
 		return true
 	}
 
-	if ctx.Host() {
+	if !android.IsModulePreferred(ctx.Module()) {
+		return true
+	}
+
+	global := dexpreopt.GetGlobalConfig(ctx)
+
+	if global.DisablePreopt {
+		return true
+	}
+
+	if inList(moduleName(ctx), global.DisablePreoptModules) {
 		return true
 	}
 
@@ -161,10 +165,6 @@
 		}
 	}
 
-	if !android.IsModulePreferred(ctx.Module()) {
-		return true
-	}
-
 	// TODO: contains no java code
 
 	return false
diff --git a/java/java.go b/java/java.go
index 2f9e03a..a9f3d1a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -447,6 +447,7 @@
 	JAVA_VERSION_7           = 7
 	JAVA_VERSION_8           = 8
 	JAVA_VERSION_9           = 9
+	JAVA_VERSION_11          = 11
 )
 
 func (v javaVersion) String() string {
@@ -459,6 +460,8 @@
 		return "1.8"
 	case JAVA_VERSION_9:
 		return "1.9"
+	case JAVA_VERSION_11:
+		return "11"
 	default:
 		return "unsupported"
 	}
@@ -479,8 +482,10 @@
 		return JAVA_VERSION_8
 	case "1.9", "9":
 		return JAVA_VERSION_9
-	case "10", "11":
-		ctx.PropertyErrorf("java_version", "Java language levels above 9 are not supported")
+	case "11":
+		return JAVA_VERSION_11
+	case "10":
+		ctx.PropertyErrorf("java_version", "Java language levels 10 is not supported")
 		return JAVA_VERSION_UNSUPPORTED
 	default:
 		ctx.PropertyErrorf("java_version", "Unrecognized Java language level")
@@ -545,6 +550,7 @@
 func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	j.sdkVersion = j.SdkVersion(ctx)
 	j.minSdkVersion = j.MinSdkVersion(ctx)
+	j.maxSdkVersion = j.MaxSdkVersion(ctx)
 
 	apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
 	if !apexInfo.IsForPlatform() {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 9fec08a..1e27238 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -68,7 +68,6 @@
 func platformBootclasspathFactory() android.SingletonModule {
 	m := &platformBootclasspathModule{}
 	m.AddProperties(&m.properties)
-	// TODO(satayev): split apex jars into separate configs.
 	initClasspathFragment(m, BOOTCLASSPATH)
 	android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
 	return m
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index e263cc4..2ec33a4 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -58,6 +58,10 @@
 func (p *platformSystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	configuredJars := p.configuredJars(ctx)
 	classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, p.classpathType)
+	standaloneConfiguredJars := p.standaloneConfiguredJars(ctx)
+	standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS)
+	configuredJars = configuredJars.AppendList(standaloneConfiguredJars)
+	classpathJars = append(classpathJars, standaloneClasspathJars...)
 	p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
 }
 
@@ -66,6 +70,10 @@
 	return dexpreopt.GetGlobalConfig(ctx).SystemServerJars
 }
 
+func (p *platformSystemServerClasspathModule) standaloneConfiguredJars(ctx android.ModuleContext) android.ConfiguredJarList {
+	return dexpreopt.GetGlobalConfig(ctx).StandaloneSystemServerJars
+}
+
 type SystemServerClasspathModule struct {
 	android.ModuleBase
 	android.ApexModuleBase
@@ -84,10 +92,15 @@
 }
 
 type systemServerClasspathFragmentProperties struct {
-	// The contents of this systemserverclasspath_fragment, could be either java_library, or java_sdk_library.
+	// List of system_server classpath jars, could be either java_library, or java_sdk_library.
 	//
 	// The order of this list matters as it is the order that is used in the SYSTEMSERVERCLASSPATH.
 	Contents []string
+
+	// List of jars that system_server loads dynamically using separate classloaders.
+	//
+	// The order does not matter.
+	Standalone_contents []string
 }
 
 func systemServerClasspathFactory() android.Module {
@@ -101,12 +114,16 @@
 }
 
 func (s *SystemServerClasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	if len(s.properties.Contents) == 0 {
-		ctx.PropertyErrorf("contents", "empty contents are not allowed")
+	if len(s.properties.Contents) == 0 && len(s.properties.Standalone_contents) == 0 {
+		ctx.PropertyErrorf("contents", "Either contents or standalone_contents needs to be non-empty")
 	}
 
 	configuredJars := s.configuredJars(ctx)
 	classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, s.classpathType)
+	standaloneConfiguredJars := s.standaloneConfiguredJars(ctx)
+	standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS)
+	configuredJars = configuredJars.AppendList(standaloneConfiguredJars)
+	classpathJars = append(classpathJars, standaloneClasspathJars...)
 	s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
 
 	// Collect the module directory for IDE info in java/jdeps.go.
@@ -145,6 +162,17 @@
 	return jars
 }
 
+func (s *SystemServerClasspathModule) standaloneConfiguredJars(ctx android.ModuleContext) android.ConfiguredJarList {
+	global := dexpreopt.GetGlobalConfig(ctx)
+
+	possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, s.properties.Standalone_contents, systemServerClasspathFragmentContentDepTag)
+	jars, _ := global.ApexStandaloneSystemServerJars.Filter(possibleUpdatableModules)
+
+	// TODO(jiakaiz): add a check to ensure that the contents are declared in make.
+
+	return jars
+}
+
 type systemServerClasspathFragmentContentDependencyTag struct {
 	blueprint.BaseDependencyTag
 }
@@ -192,8 +220,11 @@
 func (s *SystemServerClasspathModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
 	module := ctx.Module()
 	_, isSourceModule := module.(*SystemServerClasspathModule)
+	var deps []string
+	deps = append(deps, s.properties.Contents...)
+	deps = append(deps, s.properties.Standalone_contents...)
 
-	for _, name := range s.properties.Contents {
+	for _, name := range deps {
 		// 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 {
@@ -206,6 +237,7 @@
 // Collect information for opening IDE project files in java/jdeps.go.
 func (s *SystemServerClasspathModule) IDEInfo(dpInfo *android.IdeInfo) {
 	dpInfo.Deps = append(dpInfo.Deps, s.properties.Contents...)
+	dpInfo.Deps = append(dpInfo.Deps, s.properties.Standalone_contents...)
 	dpInfo.Paths = append(dpInfo.Paths, s.modulePaths...)
 }
 
@@ -233,14 +265,22 @@
 type systemServerClasspathFragmentSdkMemberProperties struct {
 	android.SdkMemberPropertiesBase
 
-	// Contents of the systemserverclasspath fragment
+	// List of system_server classpath jars, could be either java_library, or java_sdk_library.
+	//
+	// The order of this list matters as it is the order that is used in the SYSTEMSERVERCLASSPATH.
 	Contents []string
+
+	// List of jars that system_server loads dynamically using separate classloaders.
+	//
+	// The order does not matter.
+	Standalone_contents []string
 }
 
 func (s *systemServerClasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
 	module := variant.(*SystemServerClasspathModule)
 
 	s.Contents = module.properties.Contents
+	s.Standalone_contents = module.properties.Standalone_contents
 }
 
 func (s *systemServerClasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -250,6 +290,10 @@
 	if len(s.Contents) > 0 {
 		propertySet.AddPropertyWithTag("contents", s.Contents, requiredMemberDependency)
 	}
+
+	if len(s.Standalone_contents) > 0 {
+		propertySet.AddPropertyWithTag("standalone_contents", s.Standalone_contents, requiredMemberDependency)
+	}
 }
 
 var _ android.SdkMemberType = (*systemServerClasspathFragmentMemberType)(nil)
diff --git a/java/systemserver_classpath_fragment_test.go b/java/systemserver_classpath_fragment_test.go
index 9ad50dd..ba328e7 100644
--- a/java/systemserver_classpath_fragment_test.go
+++ b/java/systemserver_classpath_fragment_test.go
@@ -99,7 +99,7 @@
 func TestSystemServerClasspathFragmentWithoutContents(t *testing.T) {
 	prepareForTestWithSystemServerClasspath.
 		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
-			`\Qempty contents are not allowed\E`)).
+			`\QEither contents or standalone_contents needs to be non-empty\E`)).
 		RunTestWithBp(t, `
 			systemserverclasspath_fragment {
 				name: "systemserverclasspath-fragment",
diff --git a/python/androidmk.go b/python/androidmk.go
index 13b4172..ccc85ec 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -75,12 +75,6 @@
 }
 
 func (installer *pythonInstaller) AndroidMk(base *Module, entries *android.AndroidMkEntries) {
-	// Soong installation is only supported for host modules. Have Make
-	// installation trigger Soong installation.
-	if base.Target().Os.Class == android.Host {
-		entries.OutputFile = android.OptionalPathForPath(installer.path)
-	}
-
 	entries.Required = append(entries.Required, "libc++")
 	entries.ExtraEntries = append(entries.ExtraEntries,
 		func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
diff --git a/python/binary.go b/python/binary.go
index bf6167c..af02de6 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -35,10 +35,10 @@
 }
 
 type bazelPythonBinaryAttributes struct {
-	Main           string
+	Main           *string
 	Srcs           bazel.LabelListAttribute
 	Deps           bazel.LabelListAttribute
-	Python_version string
+	Python_version *string
 }
 
 func PythonBinaryBp2Build(ctx android.TopDownMutatorContext) {
@@ -52,12 +52,12 @@
 		return
 	}
 
-	var main string
+	var main *string
 	for _, propIntf := range m.GetProperties() {
 		if props, ok := propIntf.(*BinaryProperties); ok {
 			// main is optional.
 			if props.Main != nil {
-				main = *props.Main
+				main = props.Main
 				break
 			}
 		}
@@ -69,13 +69,13 @@
 	// under Bionic.
 	py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, false)
 	py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false)
-	var python_version string
+	var python_version *string
 	if py3Enabled && py2Enabled {
 		panic(fmt.Errorf(
 			"error for '%s' module: bp2build's python_binary_host converter does not support "+
 				"converting a module that is enabled for both Python 2 and 3 at the same time.", m.Name()))
 	} else if py2Enabled {
-		python_version = "PY2"
+		python_version = &pyVersion2
 	} else {
 		// do nothing, since python_version defaults to PY3.
 	}
diff --git a/python/library.go b/python/library.go
index d136a4e..b920117 100644
--- a/python/library.go
+++ b/python/library.go
@@ -21,6 +21,7 @@
 
 	"android/soong/android"
 	"android/soong/bazel"
+
 	"github.com/google/blueprint/proptools"
 )
 
@@ -46,7 +47,7 @@
 type bazelPythonLibraryAttributes struct {
 	Srcs         bazel.LabelListAttribute
 	Deps         bazel.LabelListAttribute
-	Srcs_version string
+	Srcs_version *string
 }
 
 func PythonLibraryHostBp2Build(ctx android.TopDownMutatorContext) {
@@ -74,11 +75,11 @@
 	// Bionic.
 	py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, true)
 	py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false)
-	var python_version string
+	var python_version *string
 	if py2Enabled && !py3Enabled {
-		python_version = "PY2"
+		python_version = &pyVersion2
 	} else if !py2Enabled && py3Enabled {
-		python_version = "PY3"
+		python_version = &pyVersion3
 	} else if !py2Enabled && !py3Enabled {
 		panic(fmt.Errorf(
 			"error for '%s' module: bp2build's %s converter doesn't understand having "+
diff --git a/rust/config/global.go b/rust/config/global.go
index d3826ac..78c8dae 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
 var pctx = android.NewPackageContext("android/soong/rust/config")
 
 var (
-	RustDefaultVersion = "1.56.1p1"
+	RustDefaultVersion = "1.57.0"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2018"
 	Stdlibs            = []string{
@@ -47,6 +47,7 @@
 		"-C opt-level=3",
 		"-C relocation-model=pic",
 		"-C overflow-checks=on",
+		"-C force-unwind-tables=yes",
 		// Use v0 mangling to distinguish from C++ symbols
 		"-Z symbol-mangling-version=v0",
 	}
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 730d756..4c847a1 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -47,15 +47,6 @@
     srcs: [
         "manifest.py",
     ],
-    version: {
-        py2: {
-            // TODO(b/203436762) Remove when system/apex/apexer/apexer.py is converted
-            enabled: true,
-        },
-        py3: {
-            enabled: true,
-        },
-    },
     visibility: ["//system/apex/apexer:__pkg__"],
 }
 
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index c32cde0..a87b9cf 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -516,7 +516,9 @@
 }
 
 type bazelShBinaryAttributes struct {
-	Srcs bazel.LabelListAttribute
+	Srcs     bazel.LabelListAttribute
+	Filename string
+	Sub_dir  string
 	// Bazel also supports the attributes below, but (so far) these are not required for Bionic
 	// deps
 	// data
@@ -547,12 +549,25 @@
 	srcs := bazel.MakeLabelListAttribute(
 		android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src}))
 
+	var filename string
+	if m.properties.Filename != nil {
+		filename = *m.properties.Filename
+	}
+
+	var subDir string
+	if m.properties.Sub_dir != nil {
+		subDir = *m.properties.Sub_dir
+	}
+
 	attrs := &bazelShBinaryAttributes{
-		Srcs: srcs,
+		Srcs:     srcs,
+		Filename: filename,
+		Sub_dir:  subDir,
 	}
 
 	props := bazel.BazelTargetModuleProperties{
-		Rule_class: "sh_binary",
+		Rule_class:        "sh_binary",
+		Bzl_load_location: "//build/bazel/rules:sh_binary.bzl",
 	}
 
 	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)