Define product_available property

To make a module available to product variants, it must define
`product_available: true`. `vendor_available: true` will not create
product variants any more.
However, in this CL, we don't change the behavior of
`vendor_available` property. It still creates both variants. After we
update all Android.bp files that need to provide product variants
with `product_available: true`, we may upload the remaining patches.

Bug: 150902910
Test: lunch aosp_arm64-userdebug && m
Change-Id: I0fd5be7bbae2c45d5cab3c3c2ca49f53a9b6f975
diff --git a/Android.bp b/Android.bp
index 4d69877..e7a5de2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -46,6 +46,7 @@
     name: "libatomic",
     defaults: ["linux_bionic_supported"],
     vendor_available: true,
+    product_available: true,
     ramdisk_available: true,
     vendor_ramdisk_available: true,
     recovery_available: true,
@@ -71,6 +72,7 @@
     name: "libgcc",
     defaults: ["linux_bionic_supported"],
     vendor_available: true,
+    product_available: true,
     recovery_available: true,
     native_bridge_supported: true,
 
@@ -94,6 +96,7 @@
     name: "libgcc_stripped",
     defaults: ["linux_bionic_supported"],
     vendor_available: true,
+    product_available: true,
     ramdisk_available: true,
     vendor_ramdisk_available: true,
     recovery_available: true,
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 8b1f40d..09d9c44 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2349,6 +2349,7 @@
 				enabled: true,
 			},
 			vendor_available: true,
+			product_available: true,
 		}
 		cc_library {
 			name: "libvendor",
@@ -3022,6 +3023,7 @@
 			name: "libvndk",
 			srcs: ["mylib.cpp"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3034,6 +3036,7 @@
 			name: "libvndksp",
 			srcs: ["mylib.cpp"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -3075,6 +3078,7 @@
 			name: "libvndk",
 			srcs: ["libvndk.so"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3087,6 +3091,7 @@
 			name: "libvndk.arm",
 			srcs: ["libvndk.arm.so"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3159,6 +3164,7 @@
 			name: "libvndk27",
 			version: "27",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3178,6 +3184,7 @@
 			name: "libvndk27",
 			version: "27",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3231,6 +3238,7 @@
 			name: "libvndk",
 			srcs: ["mylib.cpp"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3242,6 +3250,7 @@
 			name: "libvndk",
 			version: "27",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3301,6 +3310,7 @@
 			name: "libvndk",
 			srcs: ["mylib.cpp"],
 			vendor_available: true,
+			product_available: true,
 			native_bridge_supported: true,
 			host_supported: true,
 			vndk: {
@@ -3340,6 +3350,7 @@
 			name: "libvndk",
 			srcs: ["mylib.cpp"],
 			vendor_available: true,
+			product_available: true,
 			native_bridge_supported: true,
 			host_supported: true,
 			vndk: {
@@ -3371,6 +3382,7 @@
 			version: "27",
 			target_arch: "arm",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3387,6 +3399,7 @@
 			target_arch: "arm",
 			binder32bit: true,
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -3434,6 +3447,7 @@
 		cc_library {
 			name: "libz",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index 60b6ed5..27d93ee 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -25,6 +25,7 @@
 			name: "libvndk",
 			srcs: ["mylib.cpp"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -37,6 +38,7 @@
 			name: "libvndksp",
 			srcs: ["mylib.cpp"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -73,6 +75,7 @@
 		cc_library {
 			name: "libfoo",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
diff --git a/cc/cc.go b/cc/cc.go
index 3297e41..1f31872 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -314,26 +314,39 @@
 type VendorProperties struct {
 	// whether this module should be allowed to be directly depended by other
 	// modules with `vendor: true`, `proprietary: true`, or `vendor_available:true`.
-	// In addition, this module should be allowed to be directly depended by
-	// product modules with `product_specific: true`.
-	// If set to true, three variants will be built separately, one like
-	// normal, another limited to the set of libraries and headers
-	// that are exposed to /vendor modules, and the other to /product modules.
+	// If set to true, two variants will be built separately, one like
+	// normal, and the other limited to the set of libraries and headers
+	// that are exposed to /vendor modules.
 	//
-	// The vendor and product variants may be used with a different (newer) /system,
+	// The vendor variant may be used with a different (newer) /system,
 	// so it shouldn't have any unversioned runtime dependencies, or
 	// make assumptions about the system that may not be true in the
 	// future.
 	//
-	// If set to false, this module becomes inaccessible from /vendor or /product
-	// modules.
+	// If set to false, this module becomes inaccessible from /vendor modules.
 	//
 	// Default value is true when vndk: {enabled: true} or vendor: true.
 	//
 	// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
-	// If PRODUCT_PRODUCT_VNDK_VERSION isn't set, product variant will not be used.
 	Vendor_available *bool
 
+	// whether this module should be allowed to be directly depended by other
+	// modules with `product_specific: true` or `product_available: true`.
+	// If set to true, an additional product variant will be built separately
+	// that is limited to the set of libraries and headers that are exposed to
+	// /product modules.
+	//
+	// The product variant may be used with a different (newer) /system,
+	// so it shouldn't have any unversioned runtime dependencies, or
+	// make assumptions about the system that may not be true in the
+	// future.
+	//
+	// It must be set to true by default for vndk: {enabled: true} modules.
+	//
+	// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
+	// and PRODUCT_PRODUCT_VNDK_VERSION isn't set.
+	Product_available *bool
+
 	// whether this module is capable of being loaded with other instance
 	// (possibly an older version) of the same module in the same process.
 	// Currently, a shared library that is a member of VNDK (vndk: {enabled: true})
@@ -899,7 +912,7 @@
 // "product" and "vendor" variant modules return true for this function.
 // When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
 // "soc_specific: true" and more vendor installed modules are included here.
-// When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "vendor_available: true" or
+// When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "product_available: true" or
 // "product_specific: true" modules are included here.
 func (c *Module) UseVndk() bool {
 	return c.Properties.VndkVersion != ""
@@ -1352,7 +1365,7 @@
 
 	_, llndk := c.linker.(*llndkStubDecorator)
 	_, llndkHeader := c.linker.(*llndkHeadersDecorator)
-	if llndk || llndkHeader || (c.UseVndk() && c.HasVendorVariant()) {
+	if llndk || llndkHeader || (c.UseVndk() && c.HasNonSystemVariants()) {
 		// .vendor.{version} suffix is added for vendor variant or .product.{version} suffix is
 		// added for product variant only when we have vendor and product variants with core
 		// variant. The suffix is not added for vendor-only or product-only module.
@@ -1993,9 +2006,9 @@
 
 	// VNDK is cc.Module supported only for now.
 	if ccFrom, ok := from.(*Module); ok && from.UseVndk() {
-		// Though vendor code is limited by the vendor mutator,
-		// each vendor-available module needs to check
-		// link-type for VNDK.
+		// Though allowed dependency is limited by the image mutator,
+		// each vendor and product module needs to check link-type
+		// for VNDK.
 		if ccTo, ok := to.(*Module); ok {
 			if ccFrom.vndkdep != nil {
 				ccFrom.vndkdep.vndkCheckLinkType(ctx, ccTo, tag)
@@ -2126,9 +2139,10 @@
 			return false
 		}
 
-		// Even if target lib has no vendor variant, keep checking dependency graph
-		// in case it depends on vendor_available but not double_loadable transtively.
-		if !to.HasVendorVariant() {
+		// Even if target lib has no vendor variant, keep checking dependency
+		// graph in case it depends on vendor_available or product_available
+		// but not double_loadable transtively.
+		if !to.HasNonSystemVariants() {
 			return true
 		}
 
@@ -2771,6 +2785,7 @@
 			return "native:vndk_private"
 		}
 		if c.IsVndk() && !c.isVndkExt() {
+			// Product_available, if defined, must have the same value with Vendor_available.
 			if Bool(c.VendorProperties.Vendor_available) {
 				return "native:vndk"
 			}
@@ -3008,38 +3023,6 @@
 	return module
 }
 
-func squashVendorSrcs(m *Module) {
-	if lib, ok := m.compiler.(*libraryDecorator); ok {
-		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
-			lib.baseCompiler.Properties.Target.Vendor.Srcs...)
-
-		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
-			lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
-
-		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
-			lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
-	}
-}
-
-func squashRecoverySrcs(m *Module) {
-	if lib, ok := m.compiler.(*libraryDecorator); ok {
-		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
-			lib.baseCompiler.Properties.Target.Recovery.Srcs...)
-
-		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
-			lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
-
-		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
-			lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
-	}
-}
-
-func squashVendorRamdiskSrcs(m *Module) {
-	if lib, ok := m.compiler.(*libraryDecorator); ok {
-		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
-	}
-}
-
 func (c *Module) IsSdkVariant() bool {
 	return c.Properties.IsSdkVariant || c.AlwaysSdk()
 }
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 3982c0c..b3bb282 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -326,6 +326,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -335,6 +336,7 @@
 		cc_library {
 			name: "libvndk_private",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -345,6 +347,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -356,6 +359,7 @@
 		cc_library {
 			name: "libvndk_sp_private",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -386,6 +390,7 @@
 
 	config := TestConfig(buildDir, android.Android, nil, bp, nil)
 	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
 	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
 
 	ctx := testCcWithConfig(t, config)
@@ -397,6 +402,11 @@
 	checkVndkModule(t, ctx, "libvndk_sp", "", true, "", vendorVariant)
 	checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", vendorVariant)
 
+	checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant)
+	checkVndkModule(t, ctx, "libvndk_private", "", false, "", productVariant)
+	checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant)
+	checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", productVariant)
+
 	// Check VNDK snapshot output.
 
 	snapshotDir := "vndk-snapshot"
@@ -454,6 +464,7 @@
 		cc_library {
 			name: "libvndk_host_supported",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -463,6 +474,7 @@
 		cc_library {
 			name: "libvndk_host_supported_but_disabled_on_device",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -503,6 +515,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -512,6 +525,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -522,6 +536,7 @@
 		cc_library {
 			name: "libvndk2",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -647,6 +662,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -665,12 +681,28 @@
 	})
 }
 
+func TestVndkModuleError(t *testing.T) {
+	// Check the error message for vendor_available and product_available properties.
+	testCcError(t, "product_available: may not have different value than `vendor_available`", `
+		cc_library {
+			name: "libvndk",
+			vendor_available: true,
+			product_available: false,
+			vndk: {
+				enabled: true,
+			},
+			nocrt: true,
+		}
+	`)
+}
+
 func TestVndkDepError(t *testing.T) {
 	// Check whether an error is emitted when a VNDK lib depends on a system lib.
 	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -689,6 +721,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -708,6 +741,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -727,6 +761,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -747,6 +782,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -758,6 +794,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -770,6 +807,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -789,6 +827,7 @@
 		cc_library {
 			name: "libvndkprivate",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -808,6 +847,7 @@
 		cc_library {
 			name: "libvndksp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -828,6 +868,7 @@
 		cc_library {
 			name: "libvndkspprivate",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -861,6 +902,7 @@
 		cc_library {
 			name: "libdoubleloadable",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -883,6 +925,7 @@
 		cc_library {
 			name: "libvndksp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -909,6 +952,7 @@
 		cc_library {
 			name: "libdoubleloadable",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -919,6 +963,7 @@
 		cc_library {
 			name: "libnondoubleloadable",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -957,6 +1002,7 @@
 	cc_library {
 		name: "libvndk",
 		vendor_available: true,
+		product_available: true,
 		vndk: {
 			enabled: true,
 		},
@@ -1090,6 +1136,7 @@
 	cc_library {
 		name: "libvndk",
 		vendor_available: true,
+		product_available: true,
 		vndk: {
 			enabled: true,
 		},
@@ -1124,6 +1171,7 @@
 		version: "BOARD",
 		target_arch: "arm64",
 		vendor_available: true,
+		product_available: true,
 		vndk: {
 			enabled: true,
 		},
@@ -1566,6 +1614,7 @@
 		cc_library {
 			name: "libnondoubleloadable",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1619,6 +1668,7 @@
 		cc_library {
 			name: "libnondoubleloadable",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1630,6 +1680,7 @@
 		cc_library {
 			name: "libdoubleloadable",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1640,6 +1691,7 @@
 		cc_library {
 			name: "libnondoubleloadable",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -1678,6 +1730,7 @@
 			name: "libvndksp",
 			shared_libs: ["libanothervndksp"],
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -1707,6 +1760,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1715,6 +1769,7 @@
 		cc_library {
 			name: "libvndk2",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1722,6 +1777,9 @@
 				vendor: {
 					suffix: "-suffix",
 				},
+				product: {
+					suffix: "-suffix",
+				},
 			},
 			nocrt: true,
 		}
@@ -1789,6 +1847,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1819,6 +1878,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1849,6 +1909,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1869,6 +1930,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1889,6 +1951,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1909,6 +1972,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1919,6 +1983,7 @@
 			name: "libvndk_ext_product",
 			product_specific: true,
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				extends: "libvndk",
@@ -1934,6 +1999,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -1956,6 +2022,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -1982,6 +2049,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -2003,6 +2071,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -2027,6 +2096,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2046,6 +2116,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2079,6 +2150,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2108,6 +2180,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2140,6 +2213,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2160,6 +2234,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2207,6 +2282,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2216,6 +2292,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2242,6 +2319,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2261,6 +2339,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2289,6 +2368,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2308,6 +2388,7 @@
 		cc_library {
 			name: "libvndk2",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2320,6 +2401,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2339,6 +2421,7 @@
 		cc_library {
 			name: "libvndk2",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2355,6 +2438,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2376,6 +2460,7 @@
 		cc_library {
 			name: "libvndk_sp_2",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2389,6 +2474,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2408,6 +2494,7 @@
 		cc_library {
 			name: "libvndk_sp2",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2434,6 +2521,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2442,6 +2530,7 @@
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2454,6 +2543,11 @@
 			nocrt: true,
 		}
 		cc_library {
+			name: "libpa",
+			product_available: true,
+			nocrt: true,
+		}
+		cc_library {
 			name: "libproduct_va",
 			product_specific: true,
 			vendor_available: true,
@@ -2466,7 +2560,7 @@
 				"libllndk",
 				"libvndk",
 				"libvndk_sp",
-				"libva",
+				"libpa",
 				"libproduct_va",
 			],
 			nocrt: true,
@@ -2538,6 +2632,7 @@
 		cc_library {
 			name: "libvndk_private",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -2581,6 +2676,7 @@
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
@@ -2588,6 +2684,7 @@
 		cc_library {
 			name: "libvndksp",
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 				support_system_process: true,
@@ -2596,6 +2693,7 @@
 		cc_library {
 			name: "libvndkprivate",
 			vendor_available: false,
+			product_available: false,
 			vndk: {
 				enabled: true,
 			},
@@ -2618,6 +2716,7 @@
 			target_arch: "arm",
 			binder32bit: true,
 			vendor_available: true,
+			product_available: true,
 			vndk: {
 				enabled: true,
 			},
diff --git a/cc/compiler.go b/cc/compiler.go
index e2a33d7..3c86d20 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -143,21 +143,21 @@
 	} `android:"arch_variant"`
 
 	Target struct {
-		Vendor struct {
-			// list of source files that should only be used in the
-			// vendor variant of the C/C++ module.
+		Vendor, Product struct {
+			// list of source files that should only be used in vendor or
+			// product variant of the C/C++ module.
 			Srcs []string `android:"path"`
 
-			// list of source files that should not be used to
-			// build the vendor variant of the C/C++ module.
+			// list of source files that should not be used to build vendor
+			// or product variant of the C/C++ module.
 			Exclude_srcs []string `android:"path"`
 
-			// List of additional cflags that should be used to build the vendor
-			// variant of the C/C++ module.
+			// List of additional cflags that should be used to build vendor
+			// or product variant of the C/C++ module.
 			Cflags []string
 
-			// list of generated sources that should not be used to
-			// build the vendor variant of the C/C++ module.
+			// list of generated sources that should not be used to build
+			// vendor or product variant of the C/C++ module.
 			Exclude_generated_sources []string
 		}
 		Recovery struct {
@@ -298,6 +298,7 @@
 	CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
 	CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
 	CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
+	CheckBadCompilerFlags(ctx, "product.cflags", compiler.Properties.Target.Product.Cflags)
 	CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
 	CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
 
@@ -473,7 +474,12 @@
 	flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...)
 	flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...)
 
-	if ctx.useVndk() {
+	if ctx.inVendor() {
+		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
+	}
+
+	if ctx.inProduct() {
+		// TODO(b/150902910): must use 'compiler.Properties.Target.Product.Cflags'
 		flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
 	}
 
diff --git a/cc/genrule.go b/cc/genrule.go
index a5a58d2..3668e2b 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -25,6 +25,7 @@
 
 type GenruleExtraProperties struct {
 	Vendor_available         *bool
+	Product_available        *bool
 	Ramdisk_available        *bool
 	Vendor_ramdisk_available *bool
 	Recovery_available       *bool
@@ -62,7 +63,7 @@
 		return false
 	}
 
-	return Bool(g.Vendor_available) || !(ctx.SocSpecific() || ctx.DeviceSpecific())
+	return Bool(g.Vendor_available) || Bool(g.Product_available) || !(ctx.SocSpecific() || ctx.DeviceSpecific())
 }
 
 func (g *GenruleExtraProperties) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
@@ -100,7 +101,8 @@
 		return variants
 	}
 
-	if Bool(g.Vendor_available) || ctx.ProductSpecific() {
+	// TODO(b/150902910): vendor_available will not create product variant. Remove Bool(g.Vendor_available)
+	if Bool(g.Vendor_available) || Bool(g.Product_available) || ctx.ProductSpecific() {
 		variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
 		if vndkVersion := ctx.DeviceConfig().ProductVndkVersion(); vndkVersion != "current" {
 			variants = append(variants, ProductVariationPrefix+vndkVersion)
diff --git a/cc/image.go b/cc/image.go
index 7b9425f..3d6769e 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -65,8 +65,9 @@
 )
 
 func (ctx *moduleContext) ProductSpecific() bool {
+	//TODO(b/150902910): Replace HasNonSystemVariants() with HasProductVariant()
 	return ctx.ModuleContext.ProductSpecific() ||
-		(ctx.mod.HasVendorVariant() && ctx.mod.inProduct())
+		(ctx.mod.HasNonSystemVariants() && ctx.mod.inProduct())
 }
 
 func (ctx *moduleContext) SocSpecific() bool {
@@ -94,12 +95,21 @@
 	return ctx.mod.InRecovery()
 }
 
-// Returns true only when this module is configured to have core, product and vendor
-// variants.
+// Returns true when this module is configured to have core and vendor variants.
 func (c *Module) HasVendorVariant() bool {
 	return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
 }
 
+// Returns true when this module is configured to have core and product variants.
+func (c *Module) HasProductVariant() bool {
+	return c.IsVndk() || Bool(c.VendorProperties.Product_available)
+}
+
+// Returns true when this module is configured to have core and either product or vendor variants.
+func (c *Module) HasNonSystemVariants() bool {
+	return c.IsVndk() || Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Product_available)
+}
+
 // Returns true if the module is "product" variant. Usually these modules are installed in /product
 func (c *Module) inProduct() bool {
 	return c.Properties.ImageVariationPrefix == ProductVariationPrefix
@@ -139,9 +149,30 @@
 	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
 	productSpecific := mctx.ProductSpecific()
 
-	if m.VendorProperties.Vendor_available != nil && vendorSpecific {
-		mctx.PropertyErrorf("vendor_available",
-			"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
+	if m.VendorProperties.Vendor_available != nil {
+		if vendorSpecific {
+			mctx.PropertyErrorf("vendor_available",
+				"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
+		}
+		// If defined, make sure vendor_available and product_available has the
+		// same value since `false` for these properties means the module is
+		// for system only but provides the variant.
+		if m.VendorProperties.Product_available != nil {
+			if Bool(m.VendorProperties.Vendor_available) != Bool(m.VendorProperties.Product_available) {
+				mctx.PropertyErrorf("product_available", "may not have different value than `vendor_available`")
+			}
+		}
+	}
+
+	if m.VendorProperties.Product_available != nil {
+		if productSpecific {
+			mctx.PropertyErrorf("product_available",
+				"doesn't make sense at the same time as `product_specific: true`")
+		}
+		if vendorSpecific {
+			mctx.PropertyErrorf("product_available",
+				"cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
+		}
 	}
 
 	if vndkdep := m.vndkdep; vndkdep != nil {
@@ -153,6 +184,9 @@
 				} else if m.VendorProperties.Vendor_available != nil {
 					mctx.PropertyErrorf("vendor_available",
 						"must not set at the same time as `vndk: {extends: \"...\"}`")
+				} else if m.VendorProperties.Product_available != nil {
+					mctx.PropertyErrorf("product_available",
+						"must not set at the same time as `vndk: {extends: \"...\"}`")
 				}
 			} else {
 				if vndkdep.isVndkExt() {
@@ -231,21 +265,25 @@
 		} else {
 			mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
 		}
-	} else if m.HasVendorVariant() && !m.isVndkExt() {
-		// This will be available in /system, /vendor and /product
-		// or a /system directory that is available to vendor and product.
+	} else if m.HasNonSystemVariants() && !m.isVndkExt() {
+		// This will be available to /system unless it is product_specific
+		// which will be handled later.
 		coreVariantNeeded = true
 
 		// We assume that modules under proprietary paths are compatible for
 		// BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
 		// PLATFORM_VNDK_VERSION.
-		if isVendorProprietaryModule(mctx) {
-			vendorVariants = append(vendorVariants, boardVndkVersion)
-		} else {
-			vendorVariants = append(vendorVariants, platformVndkVersion)
+		if m.HasVendorVariant() {
+			if isVendorProprietaryModule(mctx) {
+				vendorVariants = append(vendorVariants, boardVndkVersion)
+			} else {
+				vendorVariants = append(vendorVariants, platformVndkVersion)
+			}
 		}
 
 		// vendor_available modules are also available to /product.
+		// TODO(b/150902910): product variant will be created only if
+		// m.HasProductVariant() is true.
 		productVariants = append(productVariants, platformVndkVersion)
 		// VNDK is always PLATFORM_VNDK_VERSION
 		if !m.IsVndk() {
@@ -351,6 +389,51 @@
 	return c.Properties.ExtraVariants
 }
 
+func squashVendorSrcs(m *Module) {
+	if lib, ok := m.compiler.(*libraryDecorator); ok {
+		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
+			lib.baseCompiler.Properties.Target.Vendor.Srcs...)
+
+		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
+			lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
+
+		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
+			lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
+	}
+}
+
+func squashProductSrcs(m *Module) {
+	if lib, ok := m.compiler.(*libraryDecorator); ok {
+		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
+			lib.baseCompiler.Properties.Target.Product.Srcs...)
+
+		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
+			lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
+
+		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
+			lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
+	}
+}
+
+func squashRecoverySrcs(m *Module) {
+	if lib, ok := m.compiler.(*libraryDecorator); ok {
+		lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
+			lib.baseCompiler.Properties.Target.Recovery.Srcs...)
+
+		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
+			lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
+
+		lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
+			lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
+	}
+}
+
+func squashVendorRamdiskSrcs(m *Module) {
+	if lib, ok := m.compiler.(*libraryDecorator); ok {
+		lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
+	}
+}
+
 func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
 	m := module.(*Module)
 	if variant == android.RamdiskVariation {
@@ -376,6 +459,7 @@
 	} else if strings.HasPrefix(variant, ProductVariationPrefix) {
 		m.Properties.ImageVariationPrefix = ProductVariationPrefix
 		m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
+		// TODO (b/150902910): This will be replaced with squashProductSrcs(m).
 		squashVendorSrcs(m)
 	}
 }
diff --git a/cc/library.go b/cc/library.go
index d946629..eeddd90 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -72,7 +72,7 @@
 	Suffix *string `android:"arch_variant"`
 
 	Target struct {
-		Vendor struct {
+		Vendor, Product struct {
 			// set suffix of the name of the output
 			Suffix *string `android:"arch_variant"`
 		}
@@ -172,11 +172,11 @@
 	Export_system_include_dirs []string `android:"arch_variant"`
 
 	Target struct {
-		Vendor struct {
+		Vendor, Product struct {
 			// list of exported include directories, like
-			// export_include_dirs, that will be applied to the
-			// vendor variant of this library. This will overwrite
-			// any other declarations.
+			// export_include_dirs, that will be applied to
+			// vendor or product variant of this library.
+			// This will overwrite any other declarations.
 			Override_export_include_dirs []string
 		}
 	}
@@ -253,6 +253,7 @@
 }
 
 func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
+	// TODO(b/150902910): product variant must use Target.Product
 	if ctx.useVndk() && f.Properties.Target.Vendor.Override_export_include_dirs != nil {
 		return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs)
 	} else {
@@ -716,6 +717,7 @@
 
 	suffix := ""
 	if useVndk {
+		// TODO(b/150902910): product variant must use Target.Product
 		suffix = String(library.Properties.Target.Vendor.Suffix)
 	}
 	if suffix == "" {
@@ -812,6 +814,7 @@
 		deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...)
 		deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...)
 	}
+	// TODO(b/150902910): product variant must use Target.Product
 	if ctx.useVndk() {
 		deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
 		deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 106b2eb..3f2cf49a 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -130,6 +130,10 @@
 		pbm.AddProperty("vendor_available", true)
 	}
 
+	if proptools.Bool(ccModule.VendorProperties.Product_available) {
+		pbm.AddProperty("product_available", true)
+	}
+
 	sdkVersion := ccModule.SdkVersion()
 	if sdkVersion != "" {
 		pbm.AddProperty("sdk_version", sdkVersion)
diff --git a/cc/linker.go b/cc/linker.go
index 7f13e28..cbf8898 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -96,32 +96,32 @@
 	Runtime_libs []string `android:"arch_variant"`
 
 	Target struct {
-		Vendor struct {
-			// list of shared libs that only should be used to build the vendor
-			// variant of the C/C++ module.
+		Vendor, Product struct {
+			// list of shared libs that only should be used to build vendor or
+			// product variant of the C/C++ module.
 			Shared_libs []string
 
-			// list of static libs that only should be used to build the vendor
-			// variant of the C/C++ module.
+			// list of static libs that only should be used to build vendor or
+			// product variant of the C/C++ module.
 			Static_libs []string
 
-			// list of shared libs that should not be used to build the vendor variant
-			// of the C/C++ module.
+			// list of shared libs that should not be used to build vendor or
+			// product variant of the C/C++ module.
 			Exclude_shared_libs []string
 
-			// list of static libs that should not be used to build the vendor variant
-			// of the C/C++ module.
+			// list of static libs that should not be used to build vendor or
+			// product variant of the C/C++ module.
 			Exclude_static_libs []string
 
-			// list of header libs that should not be used to build the vendor variant
-			// of the C/C++ module.
+			// list of header libs that should not be used to build vendor or
+			// product variant of the C/C++ module.
 			Exclude_header_libs []string
 
-			// list of runtime libs that should not be installed along with the vendor
-			// variant of the C/C++ module.
+			// list of runtime libs that should not be installed along with
+			// vendor or variant of the C/C++ module.
 			Exclude_runtime_libs []string
 
-			// version script for this vendor variant
+			// version script for vendor or product variant
 			Version_script *string `android:"arch_variant"`
 		}
 		Recovery struct {
@@ -243,6 +243,7 @@
 		deps.WholeStaticLibs = append(deps.WholeStaticLibs, "libbuildversion")
 	}
 
+	// TODO(b/150902910): product variant must use Target.Product
 	if ctx.useVndk() {
 		deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Vendor.Shared_libs...)
 		deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Vendor.Exclude_shared_libs)
@@ -479,6 +480,7 @@
 		versionScript := ctx.ExpandOptionalSource(
 			linker.Properties.Version_script, "version_script")
 
+		// TODO(b/150902910): product variant must use Target.Product
 		if ctx.useVndk() && linker.Properties.Target.Vendor.Version_script != nil {
 			versionScript = ctx.ExpandOptionalSource(
 				linker.Properties.Target.Vendor.Version_script,
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 3b1d2f43..212720b 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -55,9 +55,11 @@
 	// Whether the system library uses symbol versions.
 	Unversioned *bool
 
-	// whether this module can be directly depended upon by libs that are installed to /vendor.
-	// When set to false, this module can only be depended on by VNDK libraries, not vendor
-	// libraries. This effectively hides this module from vendors. Default value is true.
+	// whether this module can be directly depended upon by libs that are installed
+	// to /vendor and /product.
+	// When set to false, this module can only be depended on by VNDK libraries, not
+	// vendor nor product libraries. This effectively hides this module from
+	// non-system modules. Default value is true.
 	Vendor_available *bool
 
 	// list of llndk headers to re-export include directories from.
diff --git a/cc/testing.go b/cc/testing.go
index 019a186..388a9ce 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -40,6 +40,7 @@
 			name: "libatomic",
 			defaults: ["linux_bionic_supported"],
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			native_bridge_supported: true,
 			src: "",
@@ -48,6 +49,7 @@
 		toolchain_library {
 			name: "libcompiler_rt-extras",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			src: "",
 		}
@@ -55,6 +57,7 @@
 		toolchain_library {
 			name: "libclang_rt.builtins-arm-android",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			native_bridge_supported: true,
 			src: "",
@@ -63,6 +66,7 @@
 		toolchain_library {
 			name: "libclang_rt.builtins-aarch64-android",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			native_bridge_supported: true,
 			src: "",
@@ -72,6 +76,7 @@
 			name: "libclang_rt.hwasan-aarch64-android",
 			nocrt: true,
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			system_shared_libs: [],
 			stl: "none",
@@ -85,6 +90,7 @@
 		toolchain_library {
 			name: "libclang_rt.builtins-i686-android",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			native_bridge_supported: true,
 			src: "",
@@ -94,6 +100,7 @@
 			name: "libclang_rt.builtins-x86_64-android",
 			defaults: ["linux_bionic_supported"],
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			native_bridge_supported: true,
 			src: "",
@@ -102,6 +109,7 @@
 		toolchain_library {
 			name: "libclang_rt.fuzzer-arm-android",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			src: "",
 		}
@@ -109,6 +117,7 @@
 		toolchain_library {
 			name: "libclang_rt.fuzzer-aarch64-android",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			src: "",
 		}
@@ -116,6 +125,7 @@
 		toolchain_library {
 			name: "libclang_rt.fuzzer-i686-android",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			src: "",
 		}
@@ -124,6 +134,7 @@
 			name: "libclang_rt.fuzzer-x86_64-android",
 			defaults: ["linux_bionic_supported"],
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			src: "",
 		}
@@ -131,6 +142,7 @@
 		toolchain_library {
 			name: "libclang_rt.fuzzer-x86_64",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			src: "",
 		}
@@ -139,6 +151,7 @@
 		cc_prebuilt_library_shared {
 			name: "libclang_rt.ubsan_standalone-aarch64-android",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			system_shared_libs: [],
 			srcs: [""],
@@ -148,6 +161,7 @@
 			name: "libgcc",
 			defaults: ["linux_bionic_supported"],
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			src: "",
 		}
@@ -156,6 +170,7 @@
 			name: "libgcc_stripped",
 			defaults: ["linux_bionic_supported"],
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			sdk_version: "current",
 			src: "",
@@ -173,7 +188,7 @@
 				versions: ["27", "28", "29"],
 			},
 			llndk_stubs: "libc.llndk",
-}
+		}
 		llndk_library {
 			name: "libc.llndk",
 			symbol_file: "",
@@ -206,6 +221,7 @@
 		cc_library {
 			name: "libprofile-extras",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			native_coverage: false,
 			system_shared_libs: [],
@@ -215,6 +231,7 @@
 		cc_library {
 			name: "libprofile-clang-extras",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			native_coverage: false,
 			system_shared_libs: [],
@@ -224,6 +241,7 @@
 		cc_library {
 			name: "libprofile-extras_ndk",
 			vendor_available: true,
+			product_available: true,
 			native_coverage: false,
 			system_shared_libs: [],
 			stl: "none",
@@ -233,6 +251,7 @@
 		cc_library {
 			name: "libprofile-clang-extras_ndk",
 			vendor_available: true,
+			product_available: true,
 			native_coverage: false,
 			system_shared_libs: [],
 			stl: "none",
@@ -283,6 +302,7 @@
 			system_shared_libs: [],
 			stl: "none",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			host_supported: true,
 			min_sdk_version: "29",
@@ -298,6 +318,7 @@
 			system_shared_libs: [],
 			stl: "none",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			host_supported: true,
 			min_sdk_version: "29",
@@ -318,6 +339,7 @@
 			stl: "none",
 			host_supported: false,
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 			min_sdk_version: "29",
 			apex_available: [
@@ -332,6 +354,7 @@
 			system_shared_libs: [],
 			stl: "none",
 			vendor_available: true,
+			product_available: true,
 			recovery_available: true,
 		}
 
@@ -340,6 +363,7 @@
 			defaults: ["linux_bionic_supported"],
 			recovery_available: true,
 			vendor_available: true,
+			product_available: true,
 			native_bridge_supported: true,
 			stl: "none",
 			min_sdk_version: "16",
diff --git a/cc/vndk.go b/cc/vndk.go
index b2614c5..2cac03c 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -62,8 +62,8 @@
 		// declared as a VNDK or VNDK-SP module. The vendor variant
 		// will be installed in /system instead of /vendor partition.
 		//
-		// `vendor_available` must be explicitly set to either true or
-		// false together with `vndk: {enabled: true}`.
+		// `vendor_available` and `product_available` must be explicitly
+		// set to either true or false together with `vndk: {enabled: true}`.
 		Enabled *bool
 
 		// declared as a VNDK-SP module, which is a subset of VNDK.
@@ -129,13 +129,16 @@
 	return "native:vendor:vndkspext"
 }
 
+// VNDK link type check from a module with UseVndk() == true.
 func (vndk *vndkdep) vndkCheckLinkType(ctx android.BaseModuleContext, to *Module, tag blueprint.DependencyTag) {
 	if to.linker == nil {
 		return
 	}
 	if !vndk.isVndk() {
-		// Non-VNDK modules (those installed to /vendor, /product, or /system/product) can't depend
-		// on modules marked with vendor_available: false.
+		// Non-VNDK modules those installed to /vendor or /system/vendor
+		// can't depend on modules marked with vendor_available: false;
+		// or those installed to /product or /system/product can't depend
+		// on modules marked with product_available: false.
 		violation := false
 		if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) {
 			violation = true
@@ -174,6 +177,7 @@
 				to.Name())
 			return
 		}
+		// TODO(b/150902910): vndk-ext for product must check product_available.
 		if !Bool(to.VendorProperties.Vendor_available) {
 			ctx.ModuleErrorf(
 				"`extends` refers module %q which does not have `vendor_available: true`",
@@ -338,6 +342,8 @@
 	} else {
 		vndkCoreLibraries(mctx.Config())[name] = filename
 	}
+	// As `vendor_available` and `product_available` has the same value for VNDK modules,
+	// we don't need to check both values.
 	if !Bool(m.VendorProperties.Vendor_available) {
 		vndkPrivateLibraries(mctx.Config())[name] = filename
 	}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index dddd5ac..bb86717 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -34,6 +34,7 @@
 //     version: "27",
 //     target_arch: "arm64",
 //     vendor_available: true,
+//     product_available: true,
 //     vndk: {
 //         enabled: true,
 //     },
@@ -251,6 +252,7 @@
 //        version: "27",
 //        target_arch: "arm64",
 //        vendor_available: true,
+//        product_available: true,
 //        vndk: {
 //            enabled: true,
 //        },
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index edb8b30..1740ba8 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -143,6 +143,9 @@
 	// Make this module available when building for vendor
 	Vendor_available *bool
 
+	// Make this module available when building for product
+	Product_available *bool
+
 	// list of .sysprop files which defines the properties.
 	Srcs []string `android:"path"`
 
@@ -353,6 +356,7 @@
 	Recovery           *bool
 	Recovery_available *bool
 	Vendor_available   *bool
+	Product_available  *bool
 	Host_supported     *bool
 	Apex_available     []string
 	Min_sdk_version    *string
@@ -449,6 +453,7 @@
 	ccProps.Target.Host.Static_libs = []string{"libbase", "liblog"}
 	ccProps.Recovery_available = m.properties.Recovery_available
 	ccProps.Vendor_available = m.properties.Vendor_available
+	ccProps.Product_available = m.properties.Product_available
 	ccProps.Host_supported = m.properties.Host_supported
 	ccProps.Apex_available = m.ApexProperties.Apex_available
 	ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version