Merge "Add apex.use_vndk_as_stable property"
diff --git a/apex/apex.go b/apex/apex.go
index 1cfb583..f9c902c 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -691,6 +691,14 @@
 		MinSdkVersion: a.minSdkVersion(mctx),
 		Updatable:     a.Updatable(),
 	}
+
+	useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
+	excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
+	if !useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) {
+		mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
+		return
+	}
+
 	mctx.WalkDeps(func(child, parent android.Module) bool {
 		am, ok := child.(android.ApexModule)
 		if !ok || !am.CanHaveApexVariants() {
@@ -699,6 +707,11 @@
 		if !parent.(android.DepIsInSameApex).DepIsInSameApex(mctx, child) && !inAnySdk(child) {
 			return false
 		}
+		if excludeVndkLibs {
+			if c, ok := child.(*cc.Module); ok && c.IsVndk() {
+				return false
+			}
+		}
 
 		depName := mctx.OtherModuleName(child)
 		// If the parent is apexBundle, this child is directly depended.
@@ -1009,6 +1022,11 @@
 
 	// The minimum SDK version that this apex must be compatibile with.
 	Min_sdk_version *string
+
+	// If set true, VNDK libs are considered as stable libs and are not included in this apex.
+	// Should be only used in non-system apexes (e.g. vendor: true).
+	// Default is false.
+	Use_vndk_as_stable *bool
 }
 
 type apexTargetBundleProperties struct {
@@ -1826,7 +1844,8 @@
 
 	// Because APEXes targeting other than system/system_ext partitions
 	// can't set apex_available, we skip checks for these APEXes
-	if ctx.SocSpecific() || ctx.DeviceSpecific() || ctx.ProductSpecific() {
+	if a.SocSpecific() || a.DeviceSpecific() ||
+		(a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
 		return
 	}
 
@@ -2142,6 +2161,13 @@
 							// don't include it in this APEX
 							return false
 						}
+						if cc.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && cc.IsVndk() {
+							// For vendor APEX with use_vndk_as_stable: true, we don't include VNDK libs
+							// and use them from VNDK APEX.
+							// TODO(b/159576928): add "vndk" as requiredDeps so that linkerconfig can make "vndk"
+							// linker namespace avaiable to this apex.
+							return false
+						}
 						af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
 						af.transitiveDep = true
 						if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
@@ -2259,7 +2285,8 @@
 
 	// APEXes targeting other than system/system_ext partitions use vendor/product variants.
 	// So we can't link them to /system/lib libs which are core variants.
-	if a.SocSpecific() || a.DeviceSpecific() || a.ProductSpecific() {
+	if a.SocSpecific() || a.DeviceSpecific() ||
+		(a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
 		a.linkToSystemLib = false
 	}
 
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 3600614..7db61d5 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2203,6 +2203,55 @@
 	ensureContains(t, androidMk, `LOCAL_MODULE_PATH := /tmp/target/product/test_device/vendor/apex`)
 }
 
+func TestVendorApex_use_vndk_as_stable(t *testing.T) {
+	ctx, _ := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			binaries: ["mybin"],
+			vendor: true,
+			use_vndk_as_stable: true,
+		}
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+		cc_binary {
+			name: "mybin",
+			vendor: true,
+			shared_libs: ["libvndk", "libvendor"],
+		}
+		cc_library {
+			name: "libvndk",
+			vndk: {
+				enabled: true,
+			},
+			vendor_available: true,
+		}
+		cc_library {
+			name: "libvendor",
+			vendor: true,
+		}
+	`)
+
+	vendorVariant := "android_vendor.VER_arm64_armv8-a"
+
+	ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_myapex").Rule("ld")
+	libs := names(ldRule.Args["libFlags"])
+	// VNDK libs(libvndk/libc++) as they are
+	ensureListContains(t, libs, buildDir+"/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
+	ensureListContains(t, libs, buildDir+"/.intermediates/libc++/"+vendorVariant+"_shared/libc++.so")
+	// non-stable Vendor libs as APEX variants
+	ensureListContains(t, libs, buildDir+"/.intermediates/libvendor/"+vendorVariant+"_shared_myapex/libvendor.so")
+
+	// VNDK libs are not included when use_vndk_as_stable: true
+	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+		"bin/mybin",
+		"lib64/libvendor.so",
+	})
+}
+
 func TestAndroidMk_UseVendorRequired(t *testing.T) {
 	ctx, config := testApex(t, `
 		apex {