OSDN Git Service

Define vndk_product namespace for product apps
authorJustin Yun <justinyun@google.com>
Tue, 18 Feb 2020 06:01:51 +0000 (15:01 +0900)
committerJustin Yun <justinyun@google.com>
Fri, 21 Feb 2020 01:42:13 +0000 (01:42 +0000)
Unbundled apps may use vndk-sp libs from the system section. However,
product apps must use the vndk-sp libs for the product vndk version
that can be different from the vendor vndk version. So we must define
a vndk namespace for product partition.

For this purpose, BuildVndkNamespace() function requires an
additional parameter to indicate which partition is using the
namespace.
Using this function, the system section has an additional namespace
called "vndk_product" which is used only for unbundled product apps.

Test: atest linkerconfig_modules_unittest
Bug: 149063221
Change-Id: I3658efdc75e5c9a0ac3b92b9afc68aff2d4cb300

contents/include/linkerconfig/namespacebuilder.h
contents/namespace/vndk.cc
contents/section/apexdefault.cc
contents/section/product.cc
contents/section/system.cc
contents/section/vendor.cc
contents/tests/configuration/vndk_test.cc

index d621325..eeb2cbf 100644 (file)
@@ -23,12 +23,16 @@ namespace android {
 namespace linkerconfig {
 namespace contents {
 
+enum class VndkUserPartition {
+  Vendor,
+  Product,
+};
+
 typedef modules::Namespace NamespaceBuilder(const Context& ctx);
 
 NamespaceBuilder BuildSystemDefaultNamespace;
 NamespaceBuilder BuildSphalNamespace;
 NamespaceBuilder BuildRsNamespace;
-NamespaceBuilder BuildVndkNamespace;
 NamespaceBuilder BuildVendorDefaultNamespace;
 NamespaceBuilder BuildSystemNamespace;
 NamespaceBuilder BuildVndkInSystemNamespace;
@@ -37,6 +41,9 @@ NamespaceBuilder BuildUnrestrictedDefaultNamespace;
 NamespaceBuilder BuildPostInstallNamespace;
 NamespaceBuilder BuildRecoveryDefaultNamespace;
 
+modules::Namespace BuildVndkNamespace(const Context& ctx,
+                                      VndkUserPartition vndk_user);
+
 modules::Namespace BuildArtNamespace(const Context& ctx,
                                      const modules::ApexInfo& apex_info);
 
index 9f36bcc..ef390b8 100644 (file)
@@ -16,9 +16,8 @@
 
 // This namespace is exclusively for vndk-sp libs.
 
-#include "linkerconfig/namespacebuilder.h"
-
 #include "linkerconfig/environment.h"
+#include "linkerconfig/namespacebuilder.h"
 
 using android::linkerconfig::modules::AsanPath;
 using android::linkerconfig::modules::Namespace;
@@ -26,41 +25,51 @@ using android::linkerconfig::modules::Namespace;
 namespace android {
 namespace linkerconfig {
 namespace contents {
-Namespace BuildVndkNamespace([[maybe_unused]] const Context& ctx) {
+Namespace BuildVndkNamespace([[maybe_unused]] const Context& ctx,
+                             VndkUserPartition vndk_user) {
   bool is_system_section = ctx.IsSystemSection() || ctx.IsApexBinaryConfig();
-  bool is_product_section = ctx.IsProductSection();
   bool is_vndklite = ctx.IsVndkliteConfig();
+  // In the system section, we need to have an additional vndk namespace for
+  // product apps. We must have a different name "vndk_product" for this
+  // namespace. "vndk_product" namespace is used only from the native_loader for
+  // product apps.
+  const char* name;
+  if (is_system_section && vndk_user == VndkUserPartition::Product) {
+    name = "vndk_product";
+  } else {
+    name = "vndk";
+  }
+
   // Isolated but visible when used in the [system] section to allow links to be
   // created at runtime, e.g. through android_link_namespaces in
   // libnativeloader. Otherwise it isn't isolated, so visibility doesn't matter.
-  Namespace ns("vndk",
+  Namespace ns(name,
                /*is_isolated=*/is_system_section,
                /*is_visible=*/is_system_section);
 
-  if (is_system_section) {
-    // It is linked from vendor HAL. It must use vendor vndk libs.
-    ns.AddSearchPath("/odm/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath("/vendor/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath(
-        "/apex/com.android.vndk.v" + Var("VENDOR_VNDK_VERSION") + "/${LIB}",
-        AsanPath::SAME_PATH);
-  } else if (is_product_section) {
-    ns.AddSearchPath("/product/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath("/product/${LIB}/vndk", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath(
-        "/apex/com.android.vndk.v" + Var("PRODUCT_VNDK_VERSION") + "/${LIB}",
-        AsanPath::SAME_PATH);
+  std::vector<std::string> lib_paths;
+  std::vector<std::string> vndk_paths;
+  std::string vndk_version;
+  if (vndk_user == VndkUserPartition::Product) {
+    lib_paths = {"/product/${LIB}/"};
+    vndk_version = Var("PRODUCT_VNDK_VERSION");
   } else {
-    ns.AddSearchPath("/odm/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath("/odm/${LIB}/vndk", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath("/vendor/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath("/vendor/${LIB}/vndk", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath(
-        "/apex/com.android.vndk.v" + Var("VENDOR_VNDK_VERSION") + "/${LIB}",
-        AsanPath::SAME_PATH);
+    // default for vendor
+    lib_paths = {"/odm/${LIB}/", "/vendor/${LIB}/"};
+    vndk_version = Var("VENDOR_VNDK_VERSION");
   }
 
-  if (is_system_section) {
+  for (const auto& lib_path : lib_paths) {
+    ns.AddSearchPath(lib_path + "vndk-sp", AsanPath::WITH_DATA_ASAN);
+    if (!is_system_section) {
+      ns.AddSearchPath(lib_path + "vndk", AsanPath::WITH_DATA_ASAN);
+    }
+  }
+  ns.AddSearchPath("/apex/com.android.vndk.v" + vndk_version + "/${LIB}",
+                   AsanPath::SAME_PATH);
+
+  if (is_system_section && vndk_user == VndkUserPartition::Vendor) {
+    // It is for vendor sp-hal
     ns.AddPermittedPath("/odm/${LIB}/hw", AsanPath::WITH_DATA_ASAN);
     ns.AddPermittedPath("/odm/${LIB}/egl", AsanPath::WITH_DATA_ASAN);
     ns.AddPermittedPath("/vendor/${LIB}/hw", AsanPath::WITH_DATA_ASAN);
@@ -76,10 +85,9 @@ Namespace BuildVndkNamespace([[maybe_unused]] const Context& ctx) {
         AsanPath::SAME_PATH);
   }
 
-  // For the [vendor] section, the links should be identical to that of the
+  // For the non-system section, the links should be identical to that of the
   // 'vndk_in_system' namespace, except the links to 'default' and 'vndk_in_system'.
-
-  if (is_product_section) {
+  if (vndk_user == VndkUserPartition::Product) {
     ns.GetLink(ctx.GetSystemNamespaceName())
         .AddSharedLib({Var("LLNDK_LIBRARIES_PRODUCT")});
   } else {
@@ -89,10 +97,12 @@ Namespace BuildVndkNamespace([[maybe_unused]] const Context& ctx) {
 
   if (!is_vndklite) {
     if (is_system_section) {
-      // The "vndk" namespace links to the system namespace for LLNDK libs above
-      // and links to "sphal" namespace for vendor libs. The ordering matters;
-      // the system namespace has higher priority than the "sphal" namespace.
-      ns.GetLink("sphal").AllowAllSharedLibs();
+      if (vndk_user == VndkUserPartition::Vendor) {
+        // The "vndk" namespace links to the system namespace for LLNDK libs above
+        // and links to "sphal" namespace for vendor libs. The ordering matters;
+        // the system namespace has higher priority than the "sphal" namespace.
+        ns.GetLink("sphal").AllowAllSharedLibs();
+      }
     } else {
       // [vendor] or [product] section
       ns.GetLink("default").AllowAllSharedLibs();
index 42948c5..041fe80 100644 (file)
@@ -43,7 +43,7 @@ Section BuildApexDefaultSection(Context& ctx, const ApexInfo& apex_info) {
   // namespace(s)
   if (apex_info.name == "com.android.media.swcodec") {
     namespaces.emplace_back(BuildSphalNamespace(ctx));
-    namespaces.emplace_back(BuildVndkNamespace(ctx));
+    namespaces.emplace_back(BuildVndkNamespace(ctx, VndkUserPartition::Vendor));
   }
 
   return BuildSection(ctx, apex_info.name, std::move(namespaces), {});
index 68da270..ab7b25a 100644 (file)
@@ -35,7 +35,7 @@ Section BuildProductSection(Context& ctx) {
   std::vector<Namespace> namespaces;
 
   namespaces.emplace_back(BuildProductDefaultNamespace(ctx));
-  namespaces.emplace_back(BuildVndkNamespace(ctx));
+  namespaces.emplace_back(BuildVndkNamespace(ctx, VndkUserPartition::Product));
   namespaces.emplace_back(BuildSystemNamespace(ctx));
 
   if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
index cf190e6..31ba6de 100644 (file)
  * limitations under the License.
  */
 
-#include "linkerconfig/sectionbuilder.h"
-
 #include "linkerconfig/common.h"
 #include "linkerconfig/context.h"
+#include "linkerconfig/environment.h"
 #include "linkerconfig/namespacebuilder.h"
 #include "linkerconfig/section.h"
+#include "linkerconfig/sectionbuilder.h"
 
 using android::linkerconfig::contents::SectionType;
 using android::linkerconfig::modules::Namespace;
@@ -36,7 +36,11 @@ Section BuildSystemSection(Context& ctx) {
   if (ctx.IsVndkAvailable()) {
     namespaces.emplace_back(BuildSphalNamespace(ctx));
     namespaces.emplace_back(BuildRsNamespace(ctx));
-    namespaces.emplace_back(BuildVndkNamespace(ctx));
+    namespaces.emplace_back(BuildVndkNamespace(ctx, VndkUserPartition::Vendor));
+    if (android::linkerconfig::modules::IsProductVndkVersionDefined()) {
+      namespaces.emplace_back(
+          BuildVndkNamespace(ctx, VndkUserPartition::Product));
+    }
   }
   return BuildSection(ctx,
                       "system",
index 8a0d755..fdff758 100644 (file)
@@ -41,7 +41,7 @@ Section BuildVendorSection(Context& ctx) {
   // section. Instead they (except libraries from APEX) will be loaded from
   // default namespace, so VNDK libraries can access private platform libraries.
   if (!is_vndklite) {
-    namespaces.emplace_back(BuildVndkNamespace(ctx));
+    namespaces.emplace_back(BuildVndkNamespace(ctx, VndkUserPartition::Vendor));
     namespaces.emplace_back(BuildSystemNamespace(ctx));
   }
 
index a7b9ee9..c9045e2 100644 (file)
@@ -50,7 +50,7 @@ std::string Search(const Namespace& ns, std::string_view soname, fsmap fs) {
 TEST(vndk_namespace, vndk_ext) {
   Context vendor_context;
   vendor_context.SetCurrentSection(SectionType::Vendor);
-  auto vndk_ns = BuildVndkNamespace(vendor_context);
+  auto vndk_ns = BuildVndkNamespace(vendor_context, VndkUserPartition::Vendor);
 
   auto libvndk = "libvndk.so";
   auto libvndksp = "libvndksp.so";