Make product libs available to unbundled product apks.

Unbundling product apps must be triggerred if the target is enforcing
the product interfaces. The device must have ro.product.vndk.version
property if its product interface is enforced.
Unbundled product apps can use product libraries.

Bug: 144534640
Bug: 127738095
Bug: 128557860
Test: check boot and basic features

Change-Id: I32b2a1bd3e4f62b6acdbfab6bd277ec1132478a2
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
index 12bba44..be902c0 100644
--- a/libnativeloader/Android.bp
+++ b/libnativeloader/Android.bp
@@ -42,6 +42,9 @@
             shared_libs: [
                 "libdl_android",
             ],
+            whole_static_libs: [
+                "PlatformProperties",
+            ],
         },
     },
     required: [
@@ -96,6 +99,7 @@
         "liblog",
         "libnativehelper",
         "libgmock",
+        "PlatformProperties",
     ],
     header_libs: [
         "libnativebridge-headers",
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index c01f804..891d75e 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -173,7 +173,8 @@
   std::string namespace_name = kClassloaderNamespaceName;
   bool unbundled_vendor_or_product_app = false;
   if ((apk_origin == APK_ORIGIN_VENDOR ||
-       (apk_origin == APK_ORIGIN_PRODUCT && target_sdk_version > 29)) &&
+       (apk_origin == APK_ORIGIN_PRODUCT &&
+        is_product_vndk_version_defined())) &&
       !is_shared) {
     unbundled_vendor_or_product_app = true;
     // For vendor / product apks, give access to the vendor / product lib even though
diff --git a/libnativeloader/native_loader_test.cpp b/libnativeloader/native_loader_test.cpp
index ae99b97..88964b7 100644
--- a/libnativeloader/native_loader_test.cpp
+++ b/libnativeloader/native_loader_test.cpp
@@ -483,7 +483,7 @@
   RunTest();
 }
 
-TEST_P(NativeLoaderTest_Create, BundledProductApp_pre30) {
+TEST_P(NativeLoaderTest_Create, BundledProductApp) {
   dex_path = "/product/app/foo/foo.apk";
   is_shared = true;
 
@@ -493,36 +493,19 @@
   RunTest();
 }
 
-TEST_P(NativeLoaderTest_Create, BundledProductApp_post30) {
-  dex_path = "/product/app/foo/foo.apk";
-  is_shared = true;
-  target_sdk_version = 30;
-
-  expected_namespace_name = "classloader-namespace-shared";
-  expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
-  SetExpectations();
-  RunTest();
-}
-
-TEST_P(NativeLoaderTest_Create, UnbundledProductApp_pre30) {
+TEST_P(NativeLoaderTest_Create, UnbundledProductApp) {
   dex_path = "/product/app/foo/foo.apk";
   is_shared = false;
-  SetExpectations();
-  RunTest();
-}
 
-TEST_P(NativeLoaderTest_Create, UnbundledProductApp_post30) {
-  dex_path = "/product/app/foo/foo.apk";
-  is_shared = false;
-  target_sdk_version = 30;
-
-  expected_namespace_name = "vendor-classloader-namespace";
-  expected_library_path = expected_library_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
-  expected_permitted_path =
-      expected_permitted_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
-  expected_shared_libs_to_platform_ns =
-      expected_shared_libs_to_platform_ns + ":" + llndk_libraries();
-  expected_link_with_vndk_ns = true;
+  if (is_product_vndk_version_defined()) {
+    expected_namespace_name = "vendor-classloader-namespace";
+    expected_library_path = expected_library_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
+    expected_permitted_path =
+        expected_permitted_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
+    expected_shared_libs_to_platform_ns =
+        expected_shared_libs_to_platform_ns + ":" + llndk_libraries();
+    expected_link_with_vndk_ns = true;
+  }
   SetExpectations();
   RunTest();
 }
diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp
index d58b4ea..40f002f 100644
--- a/libnativeloader/public_libraries.cpp
+++ b/libnativeloader/public_libraries.cpp
@@ -30,6 +30,10 @@
 #include <android-base/strings.h>
 #include <log/log.h>
 
+#if defined(__ANDROID__)
+#include <android/sysprop/VndkProperties.sysprop.h>
+#endif
+
 #include "utils.h"
 
 namespace android::nativeloader {
@@ -324,6 +328,14 @@
   return list;
 }
 
+bool is_product_vndk_version_defined() {
+#if defined(__ANDROID__)
+  return android::sysprop::VndkProperties::product_vndk_version().has_value();
+#else
+  return false;
+#endif
+}
+
 namespace internal {
 // Exported for testing
 Result<std::vector<std::string>> ParseConfig(
diff --git a/libnativeloader/public_libraries.h b/libnativeloader/public_libraries.h
index 5dfaec3..4d34e36 100644
--- a/libnativeloader/public_libraries.h
+++ b/libnativeloader/public_libraries.h
@@ -39,6 +39,10 @@
 const std::string& llndk_libraries();
 const std::string& vndksp_libraries();
 
+// Returns true if libnativeloader is running on devices and the device has
+// ro.product.vndk.version property. It returns falso for host.
+bool is_product_vndk_version_defined();
+
 // These are exported for testing
 namespace internal {