Merge "vndk-ext should come before vndk(VNDK APEX)" am: 1314c36936
am: 9cdc8764a3

Change-Id: I907637f833e088d59e2555c6e4e6a1e31a4f56d0
diff --git a/Android.bp b/Android.bp
index d7ef173..f5b3965 100644
--- a/Android.bp
+++ b/Android.bp
@@ -143,4 +143,5 @@
         "linkerconfig_modules",
         "linkerconfig_contents",
     ],
+    host_supported: true,
 }
diff --git a/contents/namespace/vndk.cc b/contents/namespace/vndk.cc
index 8b24c28..180de8b 100644
--- a/contents/namespace/vndk.cc
+++ b/contents/namespace/vndk.cc
@@ -36,13 +36,15 @@
                /*is_isolated=*/is_system_section,
                /*is_visible=*/is_system_section);
 
-  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@{VNDK_VER}/${LIB}",
-                   AsanPath::SAME_PATH);
-
-  if (!is_system_section) {
+  if (is_system_section) {
+    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@{VNDK_VER}/${LIB}",
+                     AsanPath::SAME_PATH);
+  } 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@{VNDK_VER}/${LIB}",
                      AsanPath::SAME_PATH);
diff --git a/contents/tests/configuration/vndk_test.cc b/contents/tests/configuration/vndk_test.cc
new file mode 100644
index 0000000..495c42d
--- /dev/null
+++ b/contents/tests/configuration/vndk_test.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <string>
+#include <string_view>
+#include <unordered_map>
+#include <vector>
+
+#include "linkerconfig/context.h"
+#include "linkerconfig/namespace.h"
+#include "linkerconfig/namespacebuilder.h"
+#include "linkerconfig/sectionbuilder.h"
+
+#include "gtest/gtest.h"
+
+using namespace android::linkerconfig::contents;
+using namespace android::linkerconfig::modules;
+
+namespace {
+
+typedef std::unordered_map<std::string, std::vector<std::string>> fsmap;
+
+std::string Search(const Namespace& ns, std::string_view soname, fsmap fs) {
+  // search for current search_paths
+  for (auto path : ns.SearchPaths()) {
+    auto libs = fs[path];
+    if (std::find(std::begin(libs), std::end(libs), soname) != std::end(libs)) {
+      return path;
+    }
+  }
+  return "";
+}
+
+}  // namespace
+
+TEST(vndk_namespace, vndk_ext) {
+  Context vendor_context;
+  vendor_context.SetCurrentSection(SectionType::Vendor);
+  auto vndk_ns = BuildVndkNamespace(vendor_context);
+
+  auto libvndk = "libvndk.so";
+  auto libvndksp = "libvndksp.so";
+
+  auto system_lib_path = "/system/${LIB}";
+  auto vendor_lib_path = "/vendor/${LIB}";
+  auto vendor_vndk_lib_path = "/vendor/${LIB}/vndk";
+  auto vendor_vndksp_lib_path = "/vendor/${LIB}/vndk-sp";
+  auto apex_vndk_lib_path = "/apex/com.android.vndk.v@{VNDK_VER}/${LIB}";
+
+  auto fs = fsmap{
+      {system_lib_path, {libvndk, libvndksp}},
+      {vendor_lib_path, {libvndk, libvndksp}},
+      {apex_vndk_lib_path, {libvndk, libvndksp}},
+  };
+
+  EXPECT_EQ(apex_vndk_lib_path, Search(vndk_ns, libvndk, fs));
+  EXPECT_EQ(apex_vndk_lib_path, Search(vndk_ns, libvndksp, fs));
+
+  // vndk-ext can eclipse vndk
+  fs[vendor_vndk_lib_path] = {libvndk};
+  EXPECT_EQ(vendor_vndk_lib_path, Search(vndk_ns, libvndk, fs));
+  EXPECT_EQ(apex_vndk_lib_path, Search(vndk_ns, libvndksp, fs));
+
+  // likewise, vndk-sp-ext can eclipse vndk-sp
+  fs[vendor_vndksp_lib_path] = {libvndksp};
+  EXPECT_EQ(vendor_vndk_lib_path, Search(vndk_ns, libvndk, fs));
+  EXPECT_EQ(vendor_vndksp_lib_path, Search(vndk_ns, libvndksp, fs));
+}
diff --git a/modules/include/linkerconfig/namespace.h b/modules/include/linkerconfig/namespace.h
index 9640b57..6198cd1 100644
--- a/modules/include/linkerconfig/namespace.h
+++ b/modules/include/linkerconfig/namespace.h
@@ -97,9 +97,12 @@
   void WriteConfig(ConfigWriter& writer);
   void AddWhitelisted(const std::string& path);
 
-  std::string GetName();
+  std::string GetName() const;
 
   // For test usage
+  std::vector<std::string> SearchPaths() const {
+    return search_paths_;
+  }
   bool ContainsSearchPath(const std::string& path, AsanPath path_from_asan);
   bool ContainsPermittedPath(const std::string& path, AsanPath path_from_asan);
 
diff --git a/modules/namespace.cc b/modules/namespace.cc
index 7588c84..7fcf94f 100644
--- a/modules/namespace.cc
+++ b/modules/namespace.cc
@@ -136,7 +136,7 @@
   whitelisted_.push_back(path);
 }
 
-std::string Namespace::GetName() {
+std::string Namespace::GetName() const {
   return name_;
 }
 
@@ -148,6 +148,7 @@
          (path_from_asan != AsanPath::WITH_DATA_ASAN ||
           FindFromPathList(asan_search_paths_, kDataAsanPath + path));
 }
+
 bool Namespace::ContainsPermittedPath(const std::string& path,
                                       AsanPath path_from_asan) {
   return FindFromPathList(permitted_paths_, path) &&
@@ -156,6 +157,7 @@
          (path_from_asan != AsanPath::WITH_DATA_ASAN ||
           FindFromPathList(asan_permitted_paths_, kDataAsanPath + path));
 }
+
 }  // namespace modules
 }  // namespace linkerconfig
 }  // namespace android