vendor_available:false hides a lib from vendors

When a lib is explicitly marked as `vendor_available: false`, then it
can't be directly depended by a vendor lib which is installed to /vendor
partition. This is to hide some VNDK libs (including llndk) from vendors
so that platform owners can have a freedom of modifying their ABI
without breaking vendors.

In addition, the list of the private libs are exported to the make world
as VNDK_PRIVATE_LIBRARIES.

Also, fixed a bug that allowed a vndk lib to link against to vendor
library (or vendor variant of a system lib) if the lib is prebuilt.

Bug: 64730695
Bug: 64994918
Test: Add `vendor_available: false` to libft2 and libcompiler_rt.
Add the libs to shared_libs property of a vendor library in soong
(i.e. libnbaio_mono). The build fails with the error message.

Change-Id: Iab575db96bb4f6739a592f3fa0a75124296bea0c
diff --git a/cc/vndk.go b/cc/vndk.go
index 395069b..860678d 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -27,8 +27,8 @@
 		// declared as a VNDK or VNDK-SP module. The vendor variant
 		// will be installed in /system instead of /vendor partition.
 		//
-		// `vendor_available: true` must set to together for VNDK
-		// modules.
+		// `vendor_vailable` 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.
@@ -81,6 +81,24 @@
 	if to.linker == nil {
 		return
 	}
+	if !vndk.isVndk() {
+		// Non-VNDK modules (those installed to /vendor) can't depend on modules marked with
+		// vendor_available: false.
+		violation := false
+		if lib, ok := to.linker.(*llndkStubDecorator); ok && !lib.Properties.Vendor_available {
+			violation = true
+		} else {
+			if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) {
+				// Vendor_available == nil && !Bool(Vendor_available) should be okay since
+				// it means a vendor-only library which is a valid dependency for non-VNDK
+				// modules.
+				violation = true
+			}
+		}
+		if violation {
+			ctx.ModuleErrorf("Vendor module that is not VNDK should not link to %q which is marked as `vendor_available: false`", to.Name())
+		}
+	}
 	if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
 		// Check only shared libraries.
 		// Other (static and LL-NDK) libraries are allowed to link.
@@ -102,16 +120,17 @@
 }
 
 var (
-	vndkCoreLibraries []string
-	vndkSpLibraries   []string
-	llndkLibraries    []string
-	vndkLibrariesLock sync.Mutex
+	vndkCoreLibraries    []string
+	vndkSpLibraries      []string
+	llndkLibraries       []string
+	vndkPrivateLibraries []string
+	vndkLibrariesLock    sync.Mutex
 )
 
 // gather list of vndk-core, vndk-sp, and ll-ndk libs
 func vndkMutator(mctx android.BottomUpMutatorContext) {
 	if m, ok := mctx.Module().(*Module); ok {
-		if _, ok := m.linker.(*llndkStubDecorator); ok {
+		if lib, ok := m.linker.(*llndkStubDecorator); ok {
 			vndkLibrariesLock.Lock()
 			defer vndkLibrariesLock.Unlock()
 			name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
@@ -119,22 +138,40 @@
 				llndkLibraries = append(llndkLibraries, name)
 				sort.Strings(llndkLibraries)
 			}
-		} else if lib, ok := m.linker.(*libraryDecorator); ok && lib.shared() {
-			if m.vndkdep.isVndk() {
-				vndkLibrariesLock.Lock()
-				defer vndkLibrariesLock.Unlock()
-				if m.vndkdep.isVndkSp() {
-					if !inList(m.Name(), vndkSpLibraries) {
-						vndkSpLibraries = append(vndkSpLibraries, m.Name())
-						sort.Strings(vndkSpLibraries)
+			if !lib.Properties.Vendor_available {
+				if !inList(name, vndkPrivateLibraries) {
+					vndkPrivateLibraries = append(vndkPrivateLibraries, name)
+					sort.Strings(vndkPrivateLibraries)
+				}
+			}
+		} else {
+			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()) {
+				name := strings.TrimPrefix(m.Name(), "prebuilt_")
+				if m.vndkdep.isVndk() {
+					vndkLibrariesLock.Lock()
+					defer vndkLibrariesLock.Unlock()
+					if m.vndkdep.isVndkSp() {
+						if !inList(name, vndkSpLibraries) {
+							vndkSpLibraries = append(vndkSpLibraries, name)
+							sort.Strings(vndkSpLibraries)
+						}
+					} else {
+						if !inList(name, vndkCoreLibraries) {
+							vndkCoreLibraries = append(vndkCoreLibraries, name)
+							sort.Strings(vndkCoreLibraries)
+						}
 					}
-				} else {
-					if !inList(m.Name(), vndkCoreLibraries) {
-						vndkCoreLibraries = append(vndkCoreLibraries, m.Name())
-						sort.Strings(vndkCoreLibraries)
+					if !Bool(m.VendorProperties.Vendor_available) {
+						if !inList(name, vndkPrivateLibraries) {
+							vndkPrivateLibraries = append(vndkPrivateLibraries, name)
+							sort.Strings(vndkPrivateLibraries)
+						}
 					}
 				}
 			}
 		}
+
 	}
 }