Check if product is treblelized

Previous change on handling product partition was based on the
assumption that all devices for mainline update would be product
treblelized, but it was not true. There are some upgrade devices to S
which is not product treblelized. This change checks if the device is
treblelized with first api level and product vndk version.

Bug: 305749591
Test: AOSP cuttlefish boot succeeded
Test: libnativeloader_e2e_tests passed
Change-Id: I46f9c0e253363b891bdc6b073df3cc14e9f7b5aa
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index dc92a88..1e29f4e 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -255,7 +255,7 @@
 
       // Different name is useful for debugging
       namespace_name = kVendorClassloaderNamespaceName;
-    } else if (apk_origin == APK_ORIGIN_PRODUCT) {
+    } else if (apk_origin == APK_ORIGIN_PRODUCT && is_product_treblelized()) {
       unbundled_app_origin = APK_ORIGIN_PRODUCT;
       apk_origin_msg = "unbundled product apk";
 
@@ -405,7 +405,10 @@
   auto product_libs = filter_public_libraries(target_sdk_version, uses_libraries,
                                               product_public_libraries());
   if (!product_libs.empty()) {
-    auto target_ns = NativeLoaderNamespace::GetExportedNamespace(kProductNamespaceName, is_bridged);
+    auto target_ns = system_ns;
+    if (is_product_treblelized()) {
+      target_ns = NativeLoaderNamespace::GetExportedNamespace(kProductNamespaceName, is_bridged);
+    }
     if (target_ns.ok()) {
       linked = app_ns->Link(&target_ns.value(), product_libs);
       if (!linked.ok()) {
diff --git a/libnativeloader/native_loader_test.cpp b/libnativeloader/native_loader_test.cpp
index 62fb1ee..547fded 100644
--- a/libnativeloader/native_loader_test.cpp
+++ b/libnativeloader/native_loader_test.cpp
@@ -18,9 +18,9 @@
 
 #include "native_loader_test.h"
 
-#include <dlfcn.h>
-
+#include <android-base/properties.h>
 #include <android-base/strings.h>
+#include <dlfcn.h>
 #include <gtest/gtest.h>
 
 #include "nativehelper/scoped_utf_chars.h"
@@ -378,13 +378,16 @@
   dex_path = "/product/app/foo/foo.apk";
   is_shared = false;
 
-  expected_namespace_prefix = "product-clns";
-  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 =
-      append_extended_libraries(default_public_libraries() + ":" + llndk_libraries_product());
-  expected_link_with_vndk_product_ns = true;
+  if (is_product_treblelized()) {
+    expected_namespace_prefix = "product-clns";
+    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 =
+        append_extended_libraries(default_public_libraries() + ":" + llndk_libraries_product());
+    expected_link_with_vndk_product_ns = true;
+  }
 
   SetExpectations();
   RunTest();
diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp
index 66572e7..87210c8 100644
--- a/libnativeloader/public_libraries.cpp
+++ b/libnativeloader/public_libraries.cpp
@@ -201,7 +201,9 @@
 // contains the extended public libraries that are loaded from the system namespace.
 static std::string InitProductPublicLibraries() {
   std::vector<std::string> sonames;
-  ReadExtensionLibraries("/product/etc", &sonames);
+  if (is_product_treblelized()) {
+    ReadExtensionLibraries("/product/etc", &sonames);
+  }
   std::string libs = android::base::Join(sonames, ':');
   ALOGD("InitProductPublicLibraries: %s", libs.c_str());
   return libs;
@@ -216,6 +218,9 @@
   std::vector<std::string> sonames;
   ReadExtensionLibraries("/system/etc", &sonames);
   ReadExtensionLibraries("/system_ext/etc", &sonames);
+  if (!is_product_treblelized()) {
+    ReadExtensionLibraries("/product/etc", &sonames);
+  }
   std::string libs = android::base::Join(sonames, ':');
   ALOGD("InitExtendedPublicLibraries: %s", libs.c_str());
   return libs;
@@ -256,6 +261,10 @@
 }
 
 static std::string InitLlndkLibrariesProduct() {
+  if (!is_product_treblelized()) {
+    ALOGD("InitLlndkLibrariesProduct: Product is not treblelized");
+    return "";
+  }
   std::string config_file;
   if (IsProductVndkEnabled()) {
     config_file = kLlndkLibrariesFile;
@@ -416,6 +425,19 @@
   return public_libraries;
 }
 
+bool is_product_treblelized() {
+#if defined(ART_TARGET_ANDROID)
+  // Product is not treblelized iff launching version is prior to R and
+  // ro.product.vndk.version is not defined
+  static bool product_treblelized =
+      !(android::base::GetIntProperty("ro.product.first_api_level", 0) < __ANDROID_API_R__ &&
+        !android::sysprop::VndkProperties::product_vndk_version().has_value());
+  return product_treblelized;
+#else
+  return false;
+#endif
+}
+
 std::string get_vndk_version(bool is_product_vndk) {
 #if defined(ART_TARGET_ANDROID)
   if (is_product_vndk) {
diff --git a/libnativeloader/public_libraries.h b/libnativeloader/public_libraries.h
index 7603886..1830824 100644
--- a/libnativeloader/public_libraries.h
+++ b/libnativeloader/public_libraries.h
@@ -49,6 +49,12 @@
 
 std::string get_vndk_version(bool is_product_vndk);
 
+// Returnes true if libnativeloader is running on devices and the device has
+// treblelized product partition. It returns false for host.
+// TODO: Remove this function and assume it is always true once when Mainline does not support any
+// devices launched with Q or below.
+bool is_product_treblelized();
+
 // These are exported for testing
 namespace internal {