Merge "Add filter_packages property to droiddoc"
diff --git a/android/module.go b/android/module.go
index dda526f..8076a99 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1495,6 +1495,11 @@
 	m.commonProperties.Native_bridge_supported = boolPtr(true)
 }
 
+// IsNativeBridgeSupported returns true if "native_bridge_supported" is explicitly set as "true"
+func (m *ModuleBase) IsNativeBridgeSupported() bool {
+	return proptools.Bool(m.commonProperties.Native_bridge_supported)
+}
+
 func (m *moduleContext) InstallInData() bool {
 	return m.module.InstallInData()
 }
diff --git a/apex/apex.go b/apex/apex.go
index fb4497b..5c6220f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -21,6 +21,7 @@
 	"runtime"
 	"sort"
 	"strings"
+	"sync"
 
 	"android/soong/android"
 	"android/soong/cc"
@@ -153,6 +154,7 @@
 		"com.android.media":              []string{"libbinder"},
 		"com.android.media.swcodec":      []string{"libbinder"},
 		"test_com.android.media.swcodec": []string{"libbinder"},
+		"com.android.vndk":               []string{"libbinder"},
 	}
 )
 
@@ -185,9 +187,14 @@
 
 	android.RegisterModuleType("apex", apexBundleFactory)
 	android.RegisterModuleType("apex_test", testApexBundleFactory)
+	android.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
 	android.RegisterModuleType("apex_defaults", defaultsFactory)
 	android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
 
+	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator).Parallel()
+		ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator).Parallel()
+	})
 	android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.TopDown("apex_deps", apexDepsMutator)
 		ctx.BottomUp("apex", apexMutator).Parallel()
@@ -196,6 +203,51 @@
 	})
 }
 
+var (
+	vndkApexListKey   = android.NewOnceKey("vndkApexList")
+	vndkApexListMutex sync.Mutex
+)
+
+func vndkApexList(config android.Config) map[string]*apexBundle {
+	return config.Once(vndkApexListKey, func() interface{} {
+		return map[string]*apexBundle{}
+	}).(map[string]*apexBundle)
+}
+
+// apexVndkGatherMutator gathers "apex_vndk" modules and puts them in a map with vndk_version as a key.
+func apexVndkGatherMutator(mctx android.TopDownMutatorContext) {
+	if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
+		if ab.IsNativeBridgeSupported() {
+			mctx.PropertyErrorf("native_bridge_supported", "%q doesn't support native bridge binary.", mctx.ModuleType())
+		}
+		vndkVersion := proptools.StringDefault(ab.vndkProperties.Vndk_version, mctx.DeviceConfig().PlatformVndkVersion())
+		vndkApexListMutex.Lock()
+		defer vndkApexListMutex.Unlock()
+		vndkApexList := vndkApexList(mctx.Config())
+		if other, ok := vndkApexList[vndkVersion]; ok {
+			mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other.Name())
+		}
+		vndkApexList[vndkVersion] = ab
+	}
+}
+
+// apexVndkAddDepsMutator adds (reverse) dependencies from vndk libs to apex_vndk modules.
+// It filters only libs with matching targets.
+func apexVndkAddDepsMutator(mctx android.BottomUpMutatorContext) {
+	if cc, ok := mctx.Module().(*cc.Module); ok && cc.IsVndkOnSystem() {
+		vndkApexList := vndkApexList(mctx.Config())
+		if ab, ok := vndkApexList[cc.VndkVersion()]; ok {
+			targetArch := cc.Target().String()
+			for _, target := range ab.MultiTargets() {
+				if target.String() == targetArch {
+					mctx.AddReverseDependency(mctx.Module(), sharedLibTag, ab.Name())
+					break
+				}
+			}
+		}
+	}
+}
+
 // Mark the direct and transitive dependencies of apex bundles so that they
 // can be built for the apex bundles.
 func apexDepsMutator(mctx android.TopDownMutatorContext) {
@@ -253,11 +305,14 @@
 type apexNativeDependencies struct {
 	// List of native libraries
 	Native_shared_libs []string
+
 	// List of native executables
 	Binaries []string
+
 	// List of native tests
 	Tests []string
 }
+
 type apexMultilibProperties struct {
 	// Native dependencies whose compile_multilib is "first"
 	First apexNativeDependencies
@@ -362,14 +417,17 @@
 		Android struct {
 			Multilib apexMultilibProperties
 		}
+
 		// Multilib properties only for host.
 		Host struct {
 			Multilib apexMultilibProperties
 		}
+
 		// Multilib properties only for host linux_bionic.
 		Linux_bionic struct {
 			Multilib apexMultilibProperties
 		}
+
 		// Multilib properties only for host linux_glibc.
 		Linux_glibc struct {
 			Multilib apexMultilibProperties
@@ -377,6 +435,11 @@
 	}
 }
 
+type apexVndkProperties struct {
+	// Indicates VNDK version of which this VNDK APEX bundles VNDK libs. Default is Platform VNDK Version.
+	Vndk_version *string
+}
+
 type apexFileClass int
 
 const (
@@ -475,6 +538,7 @@
 
 	properties       apexBundleProperties
 	targetProperties apexTargetBundleProperties
+	vndkProperties   apexVndkProperties
 
 	apexTypes apexPackaging
 
@@ -498,6 +562,7 @@
 	externalDeps []string
 
 	testApex bool
+	vndkApex bool
 
 	// intermediate path for apex_manifest.json
 	manifestOut android.WritablePath
@@ -708,7 +773,7 @@
 
 func (a *apexBundle) getImageVariation(config android.DeviceConfig) string {
 	if config.VndkVersion() != "" && proptools.Bool(a.properties.Use_vendor) {
-		return "vendor"
+		return "vendor." + config.PlatformVndkVersion()
 	} else {
 		return "core"
 	}
@@ -1086,11 +1151,12 @@
 
 	// remove duplicates in filesInfo
 	removeDup := func(filesInfo []apexFile) []apexFile {
-		encountered := make(map[android.Path]bool)
+		encountered := make(map[string]bool)
 		result := []apexFile{}
 		for _, f := range filesInfo {
-			if !encountered[f.builtFile] {
-				encountered[f.builtFile] = true
+			dest := filepath.Join(f.installDir, f.builtFile.Base())
+			if !encountered[dest] {
+				encountered[dest] = true
 				result = append(result, f)
 			}
 		}
@@ -1416,7 +1482,7 @@
 	})
 
 	// Install to $OUT/soong/{target,host}/.../apex
-	if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) && !a.properties.Flattened {
+	if a.installable() && (!ctx.Config().FlattenApex() || apexType.zip()) && (!a.properties.Flattened || a.flattenedConfigValue) {
 		ctx.InstallFile(a.installDir, ctx.ModuleName()+suffix, a.outputFiles[apexType])
 	}
 }
@@ -1596,7 +1662,7 @@
 				fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
 				fmt.Fprintln(w, "$(LOCAL_INSTALLED_MODULE): .KATI_IMPLICIT_OUTPUTS :=", a.flattenedOutput.String())
 
-			} else {
+			} else if !a.properties.Flattened || a.flattenedConfigValue {
 				// zip-apex is the less common type so have the name refer to the image-apex
 				// only and use {name}.zip if you want the zip-apex
 				if apexType == zipApex && a.apexTypes == both {
@@ -1629,18 +1695,9 @@
 		}}
 }
 
-func testApexBundleFactory() android.Module {
-	return ApexBundleFactory(true /*testApex*/)
-}
-
-func apexBundleFactory() android.Module {
-	return ApexBundleFactory(false /*testApex*/)
-}
-
-func ApexBundleFactory(testApex bool) android.Module {
+func newApexBundle() *apexBundle {
 	module := &apexBundle{
 		outputFiles: map[apexPackaging]android.WritablePath{},
-		testApex:    testApex,
 	}
 	module.AddProperties(&module.properties)
 	module.AddProperties(&module.targetProperties)
@@ -1652,6 +1709,39 @@
 	return module
 }
 
+func ApexBundleFactory(testApex bool) android.Module {
+	bundle := newApexBundle()
+	bundle.testApex = testApex
+	return bundle
+}
+
+func testApexBundleFactory() android.Module {
+	bundle := newApexBundle()
+	bundle.testApex = true
+	return bundle
+}
+
+func apexBundleFactory() android.Module {
+	return newApexBundle()
+}
+
+// apex_vndk creates a special variant of apex modules which contains only VNDK libraries.
+// If `vndk_version` is specified, the VNDK libraries of the specified VNDK version are gathered automatically.
+// If not specified, then the "current" versions are gathered.
+func vndkApexBundleFactory() android.Module {
+	bundle := newApexBundle()
+	bundle.vndkApex = true
+	bundle.AddProperties(&bundle.vndkProperties)
+	android.AddLoadHook(bundle, func(ctx android.LoadHookContext) {
+		ctx.AppendProperties(&struct {
+			Compile_multilib *string
+		}{
+			proptools.StringPtr("both"),
+		})
+	})
+	return bundle
+}
+
 //
 // Defaults
 //
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e2d85ae..d16917d 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -40,8 +40,9 @@
 	return
 }
 
-func testApexError(t *testing.T, pattern, bp string) {
-	ctx, config := testApexContext(t, bp)
+func testApexError(t *testing.T, pattern, bp string, handlers ...testCustomizer) {
+	t.Helper()
+	ctx, config := testApexContext(t, bp, handlers...)
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	if len(errs) > 0 {
 		android.FailIfNoMatchingErrors(t, pattern, errs)
@@ -56,8 +57,9 @@
 	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
 }
 
-func testApex(t *testing.T, bp string) (*android.TestContext, android.Config) {
-	ctx, config := testApexContext(t, bp)
+func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
+	t.Helper()
+	ctx, config := testApexContext(t, bp, handlers...)
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
 	android.FailIfErrored(t, errs)
 	_, errs = ctx.PrepareBuildActions(config)
@@ -65,37 +67,51 @@
 	return ctx, config
 }
 
-func testApexContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
+type testCustomizer func(fs map[string][]byte, config android.Config)
+
+func withFiles(files map[string][]byte) testCustomizer {
+	return func(fs map[string][]byte, config android.Config) {
+		for k, v := range files {
+			fs[k] = v
+		}
+	}
+}
+
+func withTargets(targets map[android.OsType][]android.Target) testCustomizer {
+	return func(fs map[string][]byte, config android.Config) {
+		for k, v := range targets {
+			config.Targets[k] = v
+		}
+	}
+}
+
+func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
 	config := android.TestArchConfig(buildDir, nil)
 	config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
 	config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
 	config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
 	config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("Q")
 	config.TestProductVariables.Platform_sdk_final = proptools.BoolPtr(false)
+	config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
 
 	ctx := android.NewTestArchContext()
 	ctx.RegisterModuleType("apex", android.ModuleFactoryAdaptor(apexBundleFactory))
 	ctx.RegisterModuleType("apex_test", android.ModuleFactoryAdaptor(testApexBundleFactory))
+	ctx.RegisterModuleType("apex_vndk", android.ModuleFactoryAdaptor(vndkApexBundleFactory))
 	ctx.RegisterModuleType("apex_key", android.ModuleFactoryAdaptor(apexKeyFactory))
 	ctx.RegisterModuleType("apex_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
 	ctx.RegisterModuleType("prebuilt_apex", android.ModuleFactoryAdaptor(PrebuiltFactory))
-	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
-
-	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
-		ctx.TopDown("apex_deps", apexDepsMutator)
-		ctx.BottomUp("apex", apexMutator)
-		ctx.BottomUp("apex_uses", apexUsesMutator)
-		ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
-		ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
-	})
 
 	ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
 	ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(cc.LibrarySharedFactory))
 	ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(cc.LibraryHeaderFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(cc.PrebuiltSharedLibraryFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(cc.PrebuiltStaticLibraryFactory))
 	ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(cc.BinaryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
 	ctx.RegisterModuleType("cc_test", android.ModuleFactoryAdaptor(cc.TestFactory))
 	ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
+	ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(cc.VndkPrebuiltSharedFactory))
 	ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
 	ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory))
 	ctx.RegisterModuleType("sh_binary", android.ModuleFactoryAdaptor(android.ShBinaryFactory))
@@ -105,6 +121,7 @@
 	ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
 	ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory))
 
+	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
 	ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
 	})
@@ -115,6 +132,15 @@
 		ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
 		ctx.BottomUp("version", cc.VersionMutator).Parallel()
 		ctx.BottomUp("begin", cc.BeginMutator).Parallel()
+		ctx.TopDown("apex_vndk_gather", apexVndkGatherMutator)
+		ctx.BottomUp("apex_vndk_add_deps", apexVndkAddDepsMutator)
+	})
+	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.TopDown("apex_deps", apexDepsMutator)
+		ctx.BottomUp("apex", apexMutator)
+		ctx.BottomUp("apex_uses", apexUsesMutator)
+		ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
+		ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
 	})
 
 	ctx.Register()
@@ -132,6 +158,7 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		toolchain_library {
@@ -146,6 +173,7 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		toolchain_library {
@@ -153,6 +181,7 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		toolchain_library {
@@ -160,6 +189,23 @@
 			src: "",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
+		}
+
+		toolchain_library {
+			name: "libclang_rt.builtins-x86_64-android",
+			src: "",
+			vendor_available: true,
+			recovery_available: true,
+			native_bridge_supported: true,
+		}
+
+		toolchain_library {
+			name: "libclang_rt.builtins-i686-android",
+			src: "",
+			vendor_available: true,
+			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		cc_object {
@@ -167,6 +213,7 @@
 			stl: "none",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		cc_object {
@@ -174,6 +221,7 @@
 			stl: "none",
 			vendor_available: true,
 			recovery_available: true,
+			native_bridge_supported: true,
 		}
 
 		cc_object {
@@ -189,20 +237,23 @@
 		llndk_library {
 			name: "libc",
 			symbol_file: "",
+			native_bridge_supported: true,
 		}
 
 		llndk_library {
 			name: "libm",
 			symbol_file: "",
+			native_bridge_supported: true,
 		}
 
 		llndk_library {
 			name: "libdl",
 			symbol_file: "",
+			native_bridge_supported: true,
 		}
 	`
 
-	ctx.MockFileSystem(map[string][]byte{
+	fs := map[string][]byte{
 		"Android.bp":                                        []byte(bp),
 		"build/make/target/product/security":                nil,
 		"apex_manifest.json":                                nil,
@@ -238,7 +289,13 @@
 		"frameworks/base/api/current.txt":            nil,
 		"build/make/core/proguard.flags":             nil,
 		"build/make/core/proguard_basic_keeps.flags": nil,
-	})
+	}
+
+	for _, handler := range handlers {
+		handler(fs, config)
+	}
+
+	ctx.MockFileSystem(fs)
 
 	return ctx, config
 }
@@ -992,8 +1049,8 @@
 	inputsString := strings.Join(inputsList, " ")
 
 	// ensure that the apex includes vendor variants of the direct and indirect deps
-	ensureContains(t, inputsString, "android_arm64_armv8-a_vendor_shared_myapex/mylib.so")
-	ensureContains(t, inputsString, "android_arm64_armv8-a_vendor_shared_myapex/mylib2.so")
+	ensureContains(t, inputsString, "android_arm64_armv8-a_vendor.VER_shared_myapex/mylib.so")
+	ensureContains(t, inputsString, "android_arm64_armv8-a_vendor.VER_shared_myapex/mylib2.so")
 
 	// ensure that the apex does not include core variants
 	ensureNotContains(t, inputsString, "android_arm64_armv8-a_core_shared_myapex/mylib.so")
@@ -1210,6 +1267,252 @@
 	ensureContains(t, cFlags, "-Imy_include")
 }
 
+func TestVndkApexCurrent(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		cc_library {
+			name: "libvndksp",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+				support_system_process: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`)
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
+	ensureContains(t, copyCmds, "image.apex/lib/libvndksp.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndksp.so")
+}
+
+func TestVndkApexWithPrebuilt(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_prebuilt_library_shared {
+			name: "libvndkshared",
+			srcs: ["libvndkshared.so"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`, withFiles(map[string][]byte{
+		"libvndkshared.so": nil,
+	}))
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndkshared.so")
+}
+
+func TestVndkApexVersion(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex_v27",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			vndk_version: "27",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		vndk_prebuilt_shared {
+			name: "libvndk27",
+			version: "27",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			srcs: ["libvndk27.so"],
+		}
+	`, withFiles(map[string][]byte{
+		"libvndk27.so": nil,
+	}))
+
+	apexRule := ctx.ModuleForTests("myapex_v27", "android_common_myapex_v27").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndk27.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndk27.so")
+	ensureNotContains(t, copyCmds, "image.apex/lib/libvndk.so")
+}
+
+func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
+	testApexError(t, `module "myapex_v27.*" .*: vndk_version: 27 is already defined in "myapex_v27.*"`, `
+		apex_vndk {
+			name: "myapex_v27",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			vndk_version: "27",
+		}
+		apex_vndk {
+			name: "myapex_v27_other",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			vndk_version: "27",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		vndk_prebuilt_shared {
+			name: "libvndk",
+			version: "27",
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			srcs: ["libvndk.so"],
+		}
+	`, withFiles(map[string][]byte{
+		"libvndk.so": nil,
+	}))
+}
+
+func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			native_bridge_supported: true,
+			host_supported: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`, withTargets(map[android.OsType][]android.Target{
+		android.Android: []android.Target{
+			{Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+			{Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
+			{Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Native: true, Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm64", NativeBridgeRelativePath: "x86_64"},
+			{Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Native: true, Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "arm", NativeBridgeRelativePath: "x86"},
+		},
+	}))
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+	ensureContains(t, copyCmds, "image.apex/lib/libvndk.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libvndk.so")
+
+	// apex
+	ensureNotContains(t, copyCmds, "image.apex/lib/x86/libvndk.so")
+	ensureNotContains(t, copyCmds, "image.apex/lib64/x86_64/libvndk.so")
+}
+
+func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
+	testApexError(t, `module "myapex" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
+		apex_vndk {
+			name: "myapex",
+			key: "myapex.key",
+			file_contexts: "myapex",
+			native_bridge_supported: true,
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "libvndk",
+			srcs: ["mylib.cpp"],
+			vendor_available: true,
+			native_bridge_supported: true,
+			host_supported: true,
+			vndk: {
+				enabled: true,
+			},
+			system_shared_libs: [],
+			stl: "none",
+		}
+	`)
+}
+
 func TestDependenciesInApexManifest(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 66dd838..c9d4dad 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -37,6 +37,7 @@
 	Os() android.OsType
 	Host() bool
 	useVndk() bool
+	vndkVersion() string
 	static() bool
 	inRecovery() bool
 }
@@ -109,17 +110,7 @@
 	}
 	c.subAndroidMk(&ret, c.installer)
 
-	if c.Target().NativeBridge == android.NativeBridgeEnabled {
-		ret.SubName += nativeBridgeSuffix
-	}
-
-	if c.useVndk() && c.hasVendorVariant() {
-		// .vendor suffix is added only when we will have two variants: core and vendor.
-		// The suffix is not added for vendor-only module.
-		ret.SubName += vendorSuffix
-	} else if c.inRecovery() && !c.onlyInRecovery() {
-		ret.SubName += recoverySuffix
-	}
+	ret.SubName += c.Properties.SubName
 
 	return ret
 }
@@ -357,7 +348,6 @@
 
 func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
 	ret.Class = "SHARED_LIBRARIES"
-	ret.SubName = vendorSuffix
 
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		c.libraryDecorator.androidMkWriteExportedFlags(w)
diff --git a/cc/cc.go b/cc/cc.go
index 1826f52..cda37e8 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -36,9 +36,9 @@
 	android.RegisterModuleType("cc_defaults", defaultsFactory)
 
 	android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+		ctx.BottomUp("vndk", VndkMutator).Parallel()
 		ctx.BottomUp("image", ImageMutator).Parallel()
 		ctx.BottomUp("link", LinkageMutator).Parallel()
-		ctx.BottomUp("vndk", VndkMutator).Parallel()
 		ctx.BottomUp("ndk_api", ndkApiMutator).Parallel()
 		ctx.BottomUp("test_per_src", TestPerSrcMutator).Parallel()
 		ctx.BottomUp("version", VersionMutator).Parallel()
@@ -200,7 +200,8 @@
 	PreventInstall            bool     `blueprint:"mutated"`
 	ApexesProvidingSharedLibs []string `blueprint:"mutated"`
 
-	UseVndk bool `blueprint:"mutated"`
+	VndkVersion string `blueprint:"mutated"`
+	SubName     string `blueprint:"mutated"`
 
 	// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
 	// file
@@ -478,6 +479,19 @@
 	return ""
 }
 
+// IsVndkOnSystem returns true if a module is supposed to be a vndk library provided by system to vendor
+func (c *Module) IsVndkOnSystem() bool {
+	if linker, ok := c.linker.(libraryInterface); ok {
+		return linker.shared() && c.isVndk() && c.useVndk() && !c.isVndkExt()
+	}
+
+	return false
+}
+
+func (c *Module) VndkVersion() string {
+	return c.vndkVersion()
+}
+
 func (c *Module) Init() android.Module {
 	c.AddProperties(&c.Properties, &c.VendorProperties)
 	if c.compiler != nil {
@@ -549,7 +563,7 @@
 }
 
 func (c *Module) useVndk() bool {
-	return c.Properties.UseVndk
+	return c.Properties.VndkVersion != ""
 }
 
 func (c *Module) isCoverageVariant() bool {
@@ -583,10 +597,7 @@
 }
 
 func (c *Module) vndkVersion() string {
-	if vndkdep := c.vndkdep; vndkdep != nil {
-		return vndkdep.Properties.Vndk.Version
-	}
-	return ""
+	return c.Properties.VndkVersion
 }
 
 func (c *Module) isPgoCompile() bool {
@@ -996,6 +1007,31 @@
 
 	c.makeLinkType = c.getMakeLinkType(actx)
 
+	c.Properties.SubName = ""
+
+	if c.Target().NativeBridge == android.NativeBridgeEnabled {
+		c.Properties.SubName += nativeBridgeSuffix
+	}
+
+	if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok {
+		// .vendor suffix is added for backward compatibility with VNDK snapshot whose names with
+		// such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp.
+		c.Properties.SubName += vendorSuffix
+	} else if _, ok := c.linker.(*llndkStubDecorator); ok || (c.useVndk() && c.hasVendorVariant()) {
+		// .vendor.{version} suffix is added only when we will have two variants: core and vendor.
+		// The suffix is not added for vendor-only module.
+		c.Properties.SubName += vendorSuffix
+		vendorVersion := actx.DeviceConfig().VndkVersion()
+		if vendorVersion == "current" {
+			vendorVersion = actx.DeviceConfig().PlatformVndkVersion()
+		}
+		if c.Properties.VndkVersion != vendorVersion {
+			c.Properties.SubName += "." + c.Properties.VndkVersion
+		}
+	} else if c.inRecovery() && !c.onlyInRecovery() {
+		c.Properties.SubName += recoverySuffix
+	}
+
 	ctx := &moduleContext{
 		ModuleContext: actx,
 		moduleContextImpl: moduleContextImpl{
@@ -1483,9 +1519,11 @@
 
 	if vndkdep := c.vndkdep; vndkdep != nil {
 		if vndkdep.isVndkExt() {
-			baseModuleMode := vendorMode
+			var baseModuleMode string
 			if actx.DeviceConfig().VndkVersion() == "" {
 				baseModuleMode = coreMode
+			} else {
+				baseModuleMode = c.imageVariation()
 			}
 			actx.AddVariationDependencies([]blueprint.Variation{
 				{Mutator: "image", Variation: baseModuleMode},
@@ -1508,7 +1546,7 @@
 		// Host code is not restricted
 		return
 	}
-	if from.Properties.UseVndk {
+	if from.useVndk() {
 		// Though vendor code is limited by the vendor mutator,
 		// each vendor-available module needs to check
 		// link-type for VNDK.
@@ -1915,7 +1953,15 @@
 			} else if c.useVndk() && bothVendorAndCoreVariantsExist {
 				// The vendor module in Make will have been renamed to not conflict with the core
 				// module, so update the dependency name here accordingly.
-				return libName + vendorSuffix
+				ret := libName + vendorSuffix
+				vendorVersion := ctx.DeviceConfig().VndkVersion()
+				if vendorVersion == "current" {
+					vendorVersion = ctx.DeviceConfig().PlatformVndkVersion()
+				}
+				if c.Properties.VndkVersion != vendorVersion {
+					ret += "." + c.Properties.VndkVersion
+				}
+				return ret
 			} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
 				return libName + vendorPublicLibrarySuffix
 			} else if ccDep.inRecovery() && !ccDep.onlyInRecovery() {
@@ -2101,13 +2147,12 @@
 }
 
 func (c *Module) imageVariation() string {
-	variation := "core"
 	if c.useVndk() {
-		variation = "vendor"
+		return vendorMode + "." + c.Properties.VndkVersion
 	} else if c.inRecovery() {
-		variation = "recovery"
+		return recoveryMode
 	}
-	return variation
+	return coreMode
 }
 
 func (c *Module) IDEInfo(dpInfo *android.IdeInfo) {
@@ -2184,7 +2229,7 @@
 	// SDK libraries. (which framework-private libraries can use)
 	coreMode = "core"
 
-	// vendorMode is the variant used for /vendor code that compiles
+	// vendorMode is the variant prefix used for /vendor code that compiles
 	// against the VNDK.
 	vendorMode = "vendor"
 
@@ -2248,7 +2293,10 @@
 				variants = append(variants, coreMode)
 			}
 			if vendorVariantNeeded {
-				variants = append(variants, vendorMode)
+				variants = append(variants, vendorMode+"."+mctx.DeviceConfig().PlatformVndkVersion())
+				if vndkVersion := mctx.DeviceConfig().VndkVersion(); vndkVersion != "current" {
+					variants = append(variants, vendorMode+"."+vndkVersion)
+				}
 			}
 			if recoveryVariantNeeded {
 				variants = append(variants, recoveryMode)
@@ -2320,9 +2368,16 @@
 	}
 
 	var coreVariantNeeded bool = false
-	var vendorVariantNeeded bool = false
 	var recoveryVariantNeeded bool = false
 
+	var vendorVariants []string
+
+	platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
+	deviceVndkVersion := mctx.DeviceConfig().VndkVersion()
+	if deviceVndkVersion == "current" {
+		deviceVndkVersion = platformVndkVersion
+	}
+
 	if mctx.DeviceConfig().VndkVersion() == "" {
 		// If the device isn't compiling against the VNDK, we always
 		// use the core mode.
@@ -2333,22 +2388,31 @@
 	} else if _, ok := m.linker.(*llndkStubDecorator); ok {
 		// LL-NDK stubs only exist in the vendor variant, since the
 		// real libraries will be used in the core variant.
-		vendorVariantNeeded = true
+		vendorVariants = append(vendorVariants,
+			platformVndkVersion,
+			deviceVndkVersion,
+		)
 	} else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
 		// ... and LL-NDK headers as well
-		vendorVariantNeeded = true
-	} else if _, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
+		vendorVariants = append(vendorVariants,
+			platformVndkVersion,
+			deviceVndkVersion,
+		)
+	} else if lib, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
 		// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
 		// PRODUCT_EXTRA_VNDK_VERSIONS.
-		vendorVariantNeeded = true
+		vendorVariants = append(vendorVariants, lib.version())
 	} else if m.hasVendorVariant() && !vendorSpecific {
 		// This will be available in both /system and /vendor
 		// or a /system directory that is available to vendor.
 		coreVariantNeeded = true
-		vendorVariantNeeded = true
+		vendorVariants = append(vendorVariants, platformVndkVersion)
+		if m.isVndk() {
+			vendorVariants = append(vendorVariants, deviceVndkVersion)
+		}
 	} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
 		// This will be available in /vendor (or /odm) only
-		vendorVariantNeeded = true
+		vendorVariants = append(vendorVariants, deviceVndkVersion)
 	} else {
 		// This is either in /system (or similar: /data), or is a
 		// modules built with the NDK. Modules built with the NDK
@@ -2377,17 +2441,17 @@
 	if coreVariantNeeded {
 		variants = append(variants, coreMode)
 	}
-	if vendorVariantNeeded {
-		variants = append(variants, vendorMode)
+	for _, variant := range android.FirstUniqueStrings(vendorVariants) {
+		variants = append(variants, vendorMode+"."+variant)
 	}
 	if recoveryVariantNeeded {
 		variants = append(variants, recoveryMode)
 	}
 	mod := mctx.CreateVariations(variants...)
 	for i, v := range variants {
-		if v == vendorMode {
+		if strings.HasPrefix(v, vendorMode+".") {
 			m := mod[i].(*Module)
-			m.Properties.UseVndk = true
+			m.Properties.VndkVersion = strings.TrimPrefix(v, vendorMode+".")
 			squashVendorSrcs(m)
 		} else if v == recoveryMode {
 			m := mod[i].(*Module)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index c9eb421..6275822 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -112,7 +112,7 @@
 
 const (
 	coreVariant     = "android_arm64_armv8-a_core_shared"
-	vendorVariant   = "android_arm64_armv8-a_vendor_shared"
+	vendorVariant   = "android_arm64_armv8-a_vendor.VER_shared"
 	recoveryVariant = "android_arm64_armv8-a_recovery_shared"
 )
 
@@ -328,8 +328,8 @@
 	vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
 	vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
 
-	variant := "android_arm64_armv8-a_vendor_shared"
-	variant2nd := "android_arm_armv7-a-neon_vendor_shared"
+	variant := "android_arm64_armv8-a_vendor.VER_shared"
+	variant2nd := "android_arm_armv7-a-neon_vendor.VER_shared"
 
 	checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLibPath, variant)
 	checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd)
@@ -1343,6 +1343,8 @@
 	assertArrayString(t, *vndkPrivateLibraries(config),
 		[]string{"libllndkprivate", "libvndkprivate"})
 
+	vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared"
+
 	tests := []struct {
 		variant  string
 		name     string
@@ -1353,8 +1355,8 @@
 		{vendorVariant, "libvndkprivate", "native:vndk_private"},
 		{vendorVariant, "libvendor", "native:vendor"},
 		{vendorVariant, "libvndkext", "native:vendor"},
-		{vendorVariant, "prevndk.vndk.27.arm.binder32", "native:vndk"},
 		{vendorVariant, "libllndk.llndk", "native:vndk"},
+		{vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
 		{coreVariant, "libvndk", "native:platform"},
 		{coreVariant, "libvndkprivate", "native:platform"},
 		{coreVariant, "libllndk", "native:platform"},
@@ -1792,7 +1794,7 @@
 	`)
 
 	// _static variant is used since _shared reuses *.o from the static variant
-	cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc")
+	cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor.VER_static").Rule("cc")
 	cflags := cc.Args["cFlags"]
 	if !strings.Contains(cflags, "-Imy_include") {
 		t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
@@ -1878,7 +1880,7 @@
 
 	// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
 	// and vendor variants.
-	variant = "android_arm64_armv8-a_vendor_shared"
+	variant = "android_arm64_armv8-a_vendor.VER_shared"
 
 	module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
 	checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
@@ -1894,7 +1896,7 @@
 	module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
 	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
 
-	variant = "android_arm64_armv8-a_vendor_shared"
+	variant = "android_arm64_armv8-a_vendor.VER_shared"
 	module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
 	checkRuntimeLibs(t, nil, module)
 }
@@ -2091,9 +2093,9 @@
 	}
 
 	// test if libvendor is linked to the real shared lib
-	ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld")
+	ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor.VER", 1)).Rule("ld")
 	libflags = ld.Args["libFlags"]
-	stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"})
+	stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor.VER", 1), []string{"libvendorpublic"})
 	if !strings.Contains(libflags, stubPaths[0].String()) {
 		t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
 	}
diff --git a/cc/config/global.go b/cc/config/global.go
index d873494..1bbc6f0 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -123,8 +123,8 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r365631"
-	ClangDefaultShortVersion = "9.0.6"
+	ClangDefaultVersion      = "clang-r365631b"
+	ClangDefaultShortVersion = "9.0.7"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 4d59975..9cbe800 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -76,7 +76,7 @@
 }
 
 func (stub *llndkStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
-	vndk_ver := ctx.DeviceConfig().VndkVersion()
+	vndk_ver := ctx.Module().(*Module).Properties.VndkVersion
 	if vndk_ver == "current" {
 		platform_vndk_ver := ctx.DeviceConfig().PlatformVndkVersion()
 		if !inList(platform_vndk_ver, ctx.Config().PlatformVersionCombinedCodenames()) {
@@ -177,7 +177,6 @@
 		libraryDecorator: library,
 	}
 	stub.Properties.Vendor_available = BoolPtr(true)
-	module.Properties.UseVndk = true
 	module.compiler = stub
 	module.linker = stub
 	module.installer = nil
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index a7d0308..8c72b69 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -19,8 +19,8 @@
 )
 
 func init() {
-	android.RegisterModuleType("cc_prebuilt_library_shared", prebuiltSharedLibraryFactory)
-	android.RegisterModuleType("cc_prebuilt_library_static", prebuiltStaticLibraryFactory)
+	android.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
+	android.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
 	android.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
 }
 
@@ -131,7 +131,7 @@
 
 // cc_prebuilt_library_shared installs a precompiled shared library that are
 // listed in the srcs property in the device's directory.
-func prebuiltSharedLibraryFactory() android.Module {
+func PrebuiltSharedLibraryFactory() android.Module {
 	module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported)
 	return module.Init()
 }
@@ -158,7 +158,7 @@
 
 // cc_prebuilt_library_static installs a precompiled static library that are
 // listed in the srcs property in the device's directory.
-func prebuiltStaticLibraryFactory() android.Module {
+func PrebuiltStaticLibraryFactory() android.Module {
 	module, _ := NewPrebuiltStaticLibrary(android.HostAndDeviceSupported)
 	return module.Init()
 }
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 98d78e8..edcd26e 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -72,8 +72,8 @@
 
 	ctx := CreateTestContext(bp, fs, android.Android)
 
-	ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(prebuiltSharedLibraryFactory))
-	ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(prebuiltStaticLibraryFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_shared", android.ModuleFactoryAdaptor(PrebuiltSharedLibraryFactory))
+	ctx.RegisterModuleType("cc_prebuilt_library_static", android.ModuleFactoryAdaptor(PrebuiltStaticLibraryFactory))
 	ctx.RegisterModuleType("cc_prebuilt_binary", android.ModuleFactoryAdaptor(prebuiltBinaryFactory))
 
 	ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
diff --git a/cc/test.go b/cc/test.go
index 1a0d44f..a5a3680 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -317,6 +317,10 @@
 	var configs []tradefed.Config
 	if Bool(test.Properties.Require_root) {
 		configs = append(configs, tradefed.Preparer{"com.android.tradefed.targetprep.RootTargetPreparer", nil})
+	} else {
+		var options []tradefed.Option
+		options = append(options, tradefed.Option{"force-root", "false"})
+		configs = append(configs, tradefed.Preparer{"com.android.tradefed.targetprep.RootTargetPreparer", options})
 	}
 	if Bool(test.Properties.Disable_framework) {
 		var options []tradefed.Option
diff --git a/cc/testing.go b/cc/testing.go
index 5a3993c..a0b1634 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -253,7 +253,7 @@
 	ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory))
 	ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory))
 	ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
-	ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(vndkPrebuiltSharedFactory))
+	ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(VndkPrebuiltSharedFactory))
 	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
 		ctx.BottomUp("image", ImageMutator).Parallel()
 		ctx.BottomUp("link", LinkageMutator).Parallel()
diff --git a/cc/vndk.go b/cc/vndk.go
index 698fab5..14bbf11 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -49,10 +49,6 @@
 
 		// Extending another module
 		Extends *string
-
-		// for vndk_prebuilt_shared, this is set by "version" property.
-		// Otherwise, this is set as PLATFORM_VNDK_VERSION.
-		Version string `blueprint:"mutated"`
 	}
 }
 
@@ -129,7 +125,7 @@
 		// Other (static and LL-NDK) libraries are allowed to link.
 		return
 	}
-	if !to.Properties.UseVndk {
+	if !to.useVndk() {
 		ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
 			vndk.typeName(), to.Name())
 		return
@@ -325,14 +321,6 @@
 		return
 	}
 
-	if m.isVndk() {
-		if lib, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
-			m.vndkdep.Properties.Vndk.Version = lib.version()
-		} else {
-			m.vndkdep.Properties.Vndk.Version = mctx.DeviceConfig().PlatformVndkVersion()
-		}
-	}
-
 	if _, ok := m.linker.(*llndkStubDecorator); ok {
 		processLlndkLibrary(mctx, m)
 		return
@@ -341,8 +329,8 @@
 	lib, is_lib := m.linker.(*libraryDecorator)
 	prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
 
-	if (is_lib && lib.shared()) || (is_prebuilt_lib && prebuilt_lib.shared()) {
-		if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
+	if (is_lib && lib.buildShared()) || (is_prebuilt_lib && prebuilt_lib.buildShared()) {
+		if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
 			processVndkLibrary(mctx, m)
 			return
 		}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index da357ed..8126e4a 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -167,13 +167,19 @@
 	module.stl = nil
 	module.sanitize = nil
 	library.StripProperties.Strip.None = BoolPtr(true)
-	module.Properties.UseVndk = true
 
 	prebuilt := &vndkPrebuiltLibraryDecorator{
 		libraryDecorator: library,
 	}
 
 	prebuilt.properties.Check_elf_files = BoolPtr(false)
+	prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
+	prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
+
+	// Prevent default system libs (libc, libm, and libdl) from being linked
+	if prebuilt.baseLinker.Properties.System_shared_libs == nil {
+		prebuilt.baseLinker.Properties.System_shared_libs = []string{}
+	}
 
 	module.compiler = nil
 	module.linker = prebuilt
@@ -206,11 +212,11 @@
 //            },
 //        },
 //    }
-func vndkPrebuiltSharedFactory() android.Module {
+func VndkPrebuiltSharedFactory() android.Module {
 	module := vndkPrebuiltSharedLibrary()
 	return module.Init()
 }
 
 func init() {
-	android.RegisterModuleType("vndk_prebuilt_shared", vndkPrebuiltSharedFactory)
+	android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
 }
diff --git a/java/java.go b/java/java.go
index b05d7bb..b0fc9db 100644
--- a/java/java.go
+++ b/java/java.go
@@ -398,6 +398,7 @@
 	AidlIncludeDirs() android.Paths
 	ExportedSdkLibs() []string
 	SrcJarArgs() ([]string, android.Paths)
+	BaseModuleName() string
 }
 
 type SdkLibraryDependency interface {
diff --git a/java/robolectric.go b/java/robolectric.go
index cbe3557..9669e1b 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -105,7 +105,7 @@
 	r.roboSrcJar = roboSrcJar
 
 	for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
-		r.libs = append(r.libs, ctx.OtherModuleName(dep))
+		r.libs = append(r.libs, dep.(Dependency).BaseModuleName())
 	}
 
 	// TODO: this could all be removed if tradefed was used as the test runner, it will find everything
@@ -233,6 +233,7 @@
 
 	module.AddProperties(
 		&module.Module.properties,
+		&module.Module.deviceProperties,
 		&module.Module.protoProperties,
 		&module.robolectricProperties)
 
diff --git a/scripts/strip.sh b/scripts/strip.sh
index 738f24d..f987d98 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -82,8 +82,8 @@
         # and cannot process object files that are produced with the flag. Use
         # GNU objcopy instead for now. (b/141010852)
         "${CROSS_COMPILE}objcopy" --only-keep-debug "${infile}" "${outfile}.debug"
-        "${CROSS_COMPILE}nm" -D "${infile}" --format=posix --defined-only 2> /dev/null | awk '{ print $1 }' | sort >"${outfile}.dynsyms"
-        "${CROSS_COMPILE}nm" "${infile}" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }' | sort > "${outfile}.funcsyms"
+        "${CLANG_BIN}/llvm-nm" -D "${infile}" --format=posix --defined-only 2> /dev/null | awk '{ print $1 }' | sort >"${outfile}.dynsyms"
+        "${CLANG_BIN}/llvm-nm" "${infile}" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }' | sort > "${outfile}.funcsyms"
         comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols"
         echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty.
         "${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo"
@@ -196,10 +196,10 @@
 cat <<EOF > "${depsfile}"
 ${outfile}: \
   ${infile} \
-  ${CROSS_COMPILE}nm \
   ${CROSS_COMPILE}objcopy \
-  ${CROSS_COMPILE}readelf \
-  ${CLANG_BIN}/llvm-strip \
-  ${CLANG_BIN}/llvm-objcopy
+  ${CLANG_BIN}/llvm-nm \
+  ${CLANG_BIN}/llvm-objcopy \
+  ${CLANG_BIN}/llvm-readelf \
+  ${CLANG_BIN}/llvm-strip
 
 EOF
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 5345770..8db6833 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -282,10 +282,10 @@
 
 	// Check for generated cc_library
 	for _, variant := range []string{
-		"android_arm_armv7-a-neon_vendor_shared",
-		"android_arm_armv7-a-neon_vendor_static",
-		"android_arm64_armv8-a_vendor_shared",
-		"android_arm64_armv8-a_vendor_static",
+		"android_arm_armv7-a-neon_vendor.VER_shared",
+		"android_arm_armv7-a-neon_vendor.VER_static",
+		"android_arm64_armv8-a_vendor.VER_shared",
+		"android_arm64_armv8-a_vendor.VER_static",
 	} {
 		ctx.ModuleForTests("libsysprop-platform", variant)
 		ctx.ModuleForTests("libsysprop-vendor", variant)
@@ -309,15 +309,15 @@
 
 	// Check for exported includes
 	coreVariant := "android_arm64_armv8-a_core_static"
-	vendorVariant := "android_arm64_armv8-a_vendor_static"
+	vendorVariant := "android_arm64_armv8-a_vendor.VER_static"
 
 	platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_core_static/gen/sysprop/include"
 	platformPublicCorePath := "libsysprop-platform/android_arm64_armv8-a_core_static/gen/sysprop/public/include"
-	platformPublicVendorPath := "libsysprop-platform/android_arm64_armv8-a_vendor_static/gen/sysprop/public/include"
+	platformPublicVendorPath := "libsysprop-platform/android_arm64_armv8-a_vendor.VER_static/gen/sysprop/public/include"
 
 	platformOnProductPath := "libsysprop-platform-on-product/android_arm64_armv8-a_core_static/gen/sysprop/public/include"
 
-	vendorInternalPath := "libsysprop-vendor/android_arm64_armv8-a_vendor_static/gen/sysprop/include"
+	vendorInternalPath := "libsysprop-vendor/android_arm64_armv8-a_vendor.VER_static/gen/sysprop/include"
 	vendorPublicPath := "libsysprop-vendor/android_arm64_armv8-a_core_static/gen/sysprop/public/include"
 
 	platformClient := ctx.ModuleForTests("cc-client-platform", coreVariant)
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index bfe2c36..0a2b510 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -87,6 +87,7 @@
 	// otherwise we'd have to rebuild any generated files created with
 	// those tools.
 	removeGlobs(ctx,
+		hostOut("apex"),
 		hostOut("obj/NOTICE_FILES"),
 		hostOut("obj/PACKAGING"),
 		hostOut("coverage"),