DO NOT MERGE - qt-qpr1-dev-plus-aosp-without-vendor@5915889 into stage-aosp-master

Bug: 142003500
Change-Id: Iecbfb34019dfbaa82e7c7947c849deb67ceb4da4
diff --git a/Android.bp b/Android.bp
index 3e62e89..d7ef173 100644
--- a/Android.bp
+++ b/Android.bp
@@ -59,6 +59,7 @@
         "contents/section/*.cc",
         "contents/configuration/*.cc",
         "contents/context/*.cc",
+        "contents/common/*.cc",
     ],
 }
 
@@ -142,4 +143,4 @@
         "linkerconfig_modules",
         "linkerconfig_contents",
     ],
-}
\ No newline at end of file
+}
diff --git a/contents/common/system_links.cc b/contents/common/system_links.cc
new file mode 100644
index 0000000..27ba013
--- /dev/null
+++ b/contents/common/system_links.cc
@@ -0,0 +1,45 @@
+/*
+ * 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 "linkerconfig/common.h"
+
+#include <string>
+
+#include "linkerconfig/context.h"
+#include "linkerconfig/section.h"
+
+namespace android {
+namespace linkerconfig {
+namespace contents {
+
+using android::linkerconfig::modules::Namespace;
+using android::linkerconfig::modules::Section;
+
+void AddStandardSystemLinks(const Context& ctx, Section* section) {
+  std::string system_ns_name = ctx.GetSystemNamespaceName();
+  section->ForEachNamespaces([system_ns_name](Namespace& ns) {
+    if (ns.GetName() != system_ns_name) {
+      ns.GetLink(system_ns_name)
+          .AddSharedLib({"libc.so",
+                         "libm.so",
+                         "libdl.so",
+                         "@{SANITIZER_RUNTIME_LIBRARIES}"});
+    }
+  });
+}
+}  // namespace contents
+}  // namespace linkerconfig
+}  // namespace android
diff --git a/contents/configuration/baseconfig.cc b/contents/configuration/baseconfig.cc
index 0e49b15..eca4d31 100644
--- a/contents/configuration/baseconfig.cc
+++ b/contents/configuration/baseconfig.cc
@@ -15,6 +15,7 @@
  */
 
 #include "linkerconfig/baseconfig.h"
+#include "linkerconfig/environment.h"
 #include "linkerconfig/sectionbuilder.h"
 
 using android::linkerconfig::modules::DirToSection;
@@ -57,7 +58,11 @@
 namespace contents {
 android::linkerconfig::modules::Configuration CreateBaseConfiguration() {
   std::vector<Section> sections;
+
   Context current_context;
+  if (android::linkerconfig::modules::IsVndkLiteDevice()) {
+    current_context.SetCurrentLinkerConfigType(LinkerConfigType::Vndklite);
+  }
 
   sections.emplace_back(BuildSystemSection(current_context));
   sections.emplace_back(BuildVendorSection(current_context));
diff --git a/contents/configuration/legacy.cc b/contents/configuration/legacy.cc
index aa9a1b6..70b0c4a 100644
--- a/contents/configuration/legacy.cc
+++ b/contents/configuration/legacy.cc
@@ -17,6 +17,7 @@
 #include "linkerconfig/legacy.h"
 #include "linkerconfig/sectionbuilder.h"
 
+using android::linkerconfig::contents::LinkerConfigType;
 using android::linkerconfig::modules::DirToSection;
 using android::linkerconfig::modules::Section;
 
@@ -24,7 +25,8 @@
 const std::vector<DirToSection> kDirToSection = {
     // All binaries gets the same configuration 'legacy'
     {"/system", "legacy"},
-    {"/product", "legacy"},
+    {"/@{SYSTEM_EXT:system_ext}", "legacy"},
+    {"/@{PRODUCT:product}", "legacy"},
     {"/vendor", "legacy"},
     {"/odm", "legacy"},
     {"/sbin", "legacy"},
@@ -42,6 +44,7 @@
 android::linkerconfig::modules::Configuration CreateLegacyConfiguration() {
   std::vector<Section> sections;
   Context current_context;
+  current_context.SetCurrentLinkerConfigType(LinkerConfigType::Legacy);
 
   sections.emplace_back(BuildLegacySection(current_context));
   sections.emplace_back(BuildPostInstallSection(current_context));
diff --git a/contents/context/context.cc b/contents/context/context.cc
index d8e54b8..d1535ff 100644
--- a/contents/context/context.cc
+++ b/contents/context/context.cc
@@ -27,9 +27,33 @@
   return current_section == SectionType::Vendor;
 }
 
+bool Context::IsDefaultConfig() const {
+  return current_linkerconfig_type == LinkerConfigType::Default;
+}
+
+bool Context::IsLegacyConfig() const {
+  return current_linkerconfig_type == LinkerConfigType::Legacy;
+}
+
+bool Context::IsVndkliteConfig() const {
+  return current_linkerconfig_type == LinkerConfigType::Vndklite;
+}
+
+bool Context::IsRecoveryConfig() const {
+  return current_linkerconfig_type == LinkerConfigType::Recovery;
+}
+
 void Context::SetCurrentSection(SectionType section_type) {
   current_section = section_type;
 }
+
+std::string Context::GetSystemNamespaceName() const {
+  return IsVendorSection() && !IsVndkliteConfig() ? "system" : "default";
+}
+
+void Context::SetCurrentLinkerConfigType(LinkerConfigType config_type) {
+  current_linkerconfig_type = config_type;
+}
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/include/linkerconfig/common.h b/contents/include/linkerconfig/common.h
new file mode 100644
index 0000000..9c75d19
--- /dev/null
+++ b/contents/include/linkerconfig/common.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include "linkerconfig/context.h"
+#include "linkerconfig/section.h"
+
+namespace android {
+namespace linkerconfig {
+namespace contents {
+
+using android::linkerconfig::modules::Section;
+
+// Adds links from all namespaces in the given section to the namespace for
+// /system/${LIB} for standard libraries like Bionic (libc.so, libm.so,
+// libdl.so) and applicable libclang_rt.*.
+void AddStandardSystemLinks(const Context& ctx, Section* section);
+
+}  // namespace contents
+}  // namespace linkerconfig
+}  // namespace android
diff --git a/contents/include/linkerconfig/context.h b/contents/include/linkerconfig/context.h
index f6c17e8..a2c0a7e 100644
--- a/contents/include/linkerconfig/context.h
+++ b/contents/include/linkerconfig/context.h
@@ -15,6 +15,8 @@
  */
 #pragma once
 
+#include <string>
+
 namespace android {
 namespace linkerconfig {
 namespace contents {
@@ -25,18 +27,37 @@
   Other,
 };
 
+enum class LinkerConfigType {
+  Default,
+  Legacy,
+  Vndklite,
+  Recovery,
+};
+
 class Context {
  public:
-  Context() : current_section(SectionType::System) {
+  Context()
+      : current_section(SectionType::System),
+        current_linkerconfig_type(LinkerConfigType::Default) {
   }
   bool IsSystemSection() const;
   bool IsVendorSection() const;
 
+  bool IsDefaultConfig() const;
+  bool IsLegacyConfig() const;
+  bool IsVndkliteConfig() const;
+  bool IsRecoveryConfig() const;
+
   void SetCurrentSection(SectionType value);
+  void SetCurrentLinkerConfigType(LinkerConfigType value);
+
+  // Returns the namespace that covers /system/${LIB}.
+  std::string GetSystemNamespaceName() const;
 
  private:
   SectionType current_section;
+  LinkerConfigType current_linkerconfig_type;
 };
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/include/linkerconfig/namespacebuilder.h b/contents/include/linkerconfig/namespacebuilder.h
index 6e295d9..107d3b7 100644
--- a/contents/include/linkerconfig/namespacebuilder.h
+++ b/contents/include/linkerconfig/namespacebuilder.h
@@ -26,7 +26,7 @@
 namespace contents {
 NamespaceBuilder BuildSystemDefaultNamespace;
 NamespaceBuilder BuildMediaNamespace;
-NamespaceBuilder BuildRuntimeNamespace;
+NamespaceBuilder BuildArtNamespace;
 NamespaceBuilder BuildConscryptNamespace;
 NamespaceBuilder BuildResolvNamespace;
 NamespaceBuilder BuildSphalNamespace;
@@ -40,4 +40,4 @@
 NamespaceBuilder BuildNeuralNetworksNamespace;
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/runtime.cc b/contents/namespace/art.cc
similarity index 60%
rename from contents/namespace/runtime.cc
rename to contents/namespace/art.cc
index 493c288..559ac0c 100644
--- a/contents/namespace/runtime.cc
+++ b/contents/namespace/art.cc
@@ -22,17 +22,28 @@
 namespace android {
 namespace linkerconfig {
 namespace contents {
-Namespace BuildRuntimeNamespace([[maybe_unused]] const Context& ctx) {
-  Namespace ns("runtime", /*is_isolated=*/true,
+
+Namespace BuildArtNamespace([[maybe_unused]] const Context& ctx) {
+  // Make the namespace visible to allow links to be created at runtime, e.g.
+  // through android_link_namespaces in libnativeloader. That is not applicable
+  // to the vendor section.
+  Namespace ns("art",
+               /*is_isolated=*/true,
                /*is_visible=*/!ctx.IsVendorSection());
+
   ns.AddSearchPath("/apex/com.android.art/${LIB}", AsanPath::SAME_PATH);
-  ns.AddSearchPath("/apex/com.android.runtime/${LIB}", AsanPath::SAME_PATH);
-  // TODO(b/119867084): Restrict to Bionic dlopen dependencies and PALette
-  // library when it exists.
-  ns.CreateLink(ctx.IsVendorSection() ? "system" : "default", true);
+
+  // Need allow_all_shared_libs to let libart.so dlopen oat files in
+  // /system/framework and /data.
+  // TODO(b/130340935): Use a dynamically created linker namespace similar to
+  // classloader-namespace for oat files, and tighten this up.
+  ns.GetLink(ctx.GetSystemNamespaceName()).AllowAllSharedLibs();
+
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
+
 }  // namespace contents
 }  // namespace linkerconfig
 }  // namespace android
diff --git a/contents/namespace/conscrypt.cc b/contents/namespace/conscrypt.cc
index f5d9143..2bb765d 100644
--- a/contents/namespace/conscrypt.cc
+++ b/contents/namespace/conscrypt.cc
@@ -19,16 +19,11 @@
 #include <string>
 #include <vector>
 
+#include "linkerconfig/environment.h"
+
 using android::linkerconfig::modules::AsanPath;
 using android::linkerconfig::modules::Namespace;
 
-namespace {
-const std::vector<std::string> kLibsFromDefault = {"libc.so",
-                                                   "libm.so",
-                                                   "libdl.so",
-                                                   "liblog.so"};
-}  // namespace
-
 namespace android {
 namespace linkerconfig {
 namespace contents {
@@ -37,11 +32,11 @@
                /*is_visible=*/true);
 
   ns.AddSearchPath("/apex/com.android.conscrypt/${LIB}", AsanPath::SAME_PATH);
-  ns.CreateLink("runtime").AddSharedLib("libandroidio.so");
-  ns.CreateLink("default").AddSharedLib(kLibsFromDefault);
+  ns.GetLink("art").AddSharedLib("libandroidio.so");
+  ns.GetLink(ctx.GetSystemNamespaceName()).AddSharedLib("liblog.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/media.cc b/contents/namespace/media.cc
index 4f4ab3a..0208963 100644
--- a/contents/namespace/media.cc
+++ b/contents/namespace/media.cc
@@ -22,31 +22,21 @@
 #include "linkerconfig/environment.h"
 
 using android::linkerconfig::modules::AsanPath;
+using android::linkerconfig::modules::Link;
 using android::linkerconfig::modules::Namespace;
 
 namespace {
-const std::vector<std::string> kLibsFromDefaultLegacy = {
-    "libandroid.so",
-    "libbinder_ndk.so",
-    "libc.so",
-    "libcgrouprc.so",
-    "libdl.so",
-    "liblog.so",
-    "libmediametrics.so",
-    "libmediandk.so",
-    "libm.so",
-    "libvndksupport.so",
-    "libclang_rt.asan-aarch64-android.so",
-    "libclang_rt.asan-arm-android.so",
-    "libclang_rt.asan-i686-android.so",
-    "libclang_rt.asan-x86_64-android.so",
-    "libclang_rt.hwasan-aarch64-android.so"};
+const std::vector<std::string> kLibsFromDefaultLegacy = {"libandroid.so",
+                                                         "libbinder_ndk.so",
+                                                         "libcgrouprc.so",
+                                                         "liblog.so",
+                                                         "libmediametrics.so",
+                                                         "libmediandk.so",
+                                                         "libvndksupport.so"};
 
-const std::vector<std::string> kLibsFromDefault = {
-    "@{LLNDK_LIBRARIES}",
-    "libbinder_ndk.so",
-    "libmediametrics.so",
-    "@{SANITIZER_RUNTIME_LIBRARIES}"};
+const std::vector<std::string> kLibsFromDefault = {"@{LLNDK_LIBRARIES}",
+                                                   "libbinder_ndk.so",
+                                                   "libmediametrics.so"};
 
 const std::vector<std::string> kLibsFromDefaultSystem = {"libcgrouprc.so"};
 }  // namespace
@@ -55,28 +45,30 @@
 namespace linkerconfig {
 namespace contents {
 Namespace BuildMediaNamespace([[maybe_unused]] const Context& ctx) {
-  bool is_legacy = android::linkerconfig::modules::IsLegacyDevice();
+  bool is_legacy = ctx.IsLegacyConfig();
+  bool is_vndklite = ctx.IsVndkliteConfig();
   bool is_system_section = ctx.IsSystemSection();
 
   Namespace ns("media", /*is_isolated=*/true, /*is_visible=*/true);
   ns.AddSearchPath("/apex/com.android.media/${LIB}", AsanPath::SAME_PATH);
-  ns.AddPermittedPath("/apex/com.android.media/${LIB}/extractors",
-                      AsanPath::SAME_PATH);
+  ns.AddPermittedPath(
+      "/apex/com.android.media/${LIB}/extractors",
+      (is_legacy || is_vndklite) ? AsanPath::NONE : AsanPath::SAME_PATH);
 
-  auto& link_to_default = ns.CreateLink("default");
+  Link& system_link = ns.GetLink(ctx.GetSystemNamespaceName());
   if (is_legacy) {
-    link_to_default.AddSharedLib(kLibsFromDefaultLegacy);
+    system_link.AddSharedLib(kLibsFromDefaultLegacy);
   } else {
-    link_to_default.AddSharedLib(kLibsFromDefault);
-    if (is_system_section) {
-      link_to_default.AddSharedLib(kLibsFromDefaultSystem);
+    system_link.AddSharedLib(kLibsFromDefault);
+    if (is_system_section && !is_vndklite) {
+      system_link.AddSharedLib(kLibsFromDefaultSystem);
     }
   }
 
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/neuralnetworks.cc b/contents/namespace/neuralnetworks.cc
index 0c2e759..49add82 100644
--- a/contents/namespace/neuralnetworks.cc
+++ b/contents/namespace/neuralnetworks.cc
@@ -29,13 +29,9 @@
   ns.AddSearchPath("/apex/com.android.neuralnetworks/${LIB}",
                    AsanPath::SAME_PATH);
 
-  std::string link_target = ctx.IsVendorSection() ? "system" : "default";
-  ns.CreateLink(link_target)
-      .AddSharedLib({"libc.so",
-                     "libcgrouprc.so",
-                     "libdl.so",
+  ns.GetLink(ctx.GetSystemNamespaceName())
+      .AddSharedLib({"libcgrouprc.so",
                      "liblog.so",
-                     "libm.so",
                      "libnativewindow.so",
                      "libneuralnetworks_packageinfo.so",
                      "libsync.so",
@@ -45,4 +41,4 @@
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/resolv.cc b/contents/namespace/resolv.cc
index 42850de..3156fa3 100644
--- a/contents/namespace/resolv.cc
+++ b/contents/namespace/resolv.cc
@@ -23,16 +23,10 @@
 using android::linkerconfig::modules::Namespace;
 
 namespace {
-const std::vector<std::string> kLibsFromDefault = {"libc.so",
-                                                   "libcgrouprc.so",
-                                                   "libm.so",
-                                                   "libdl.so",
+const std::vector<std::string> kLibsFromDefault = {"libcgrouprc.so",
                                                    "libbinder_ndk.so",
                                                    "liblog.so",
                                                    "libvndksupport.so"};
-
-const std::vector<std::string> kLibsFromUnrestrictedDefault =
-    {"libc.so", "libm.so", "libdl.so", "libbinder_ndk.so", "liblog.so"};
 }  // namespace
 
 namespace android {
@@ -41,11 +35,11 @@
 Namespace BuildResolvNamespace([[maybe_unused]] const Context& ctx) {
   Namespace ns("resolv", /*is_isolated=*/true, /*is_visible=*/true);
   ns.AddSearchPath("/apex/com.android.resolv/${LIB}", AsanPath::SAME_PATH);
-  ns.CreateLink("default").AddSharedLib(
-      ctx.IsSystemSection() ? kLibsFromDefault : kLibsFromUnrestrictedDefault);
+
+  ns.GetLink(ctx.GetSystemNamespaceName()).AddSharedLib(kLibsFromDefault);
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/rs.cc b/contents/namespace/rs.cc
index c1ddc42..df6e988 100644
--- a/contents/namespace/rs.cc
+++ b/contents/namespace/rs.cc
@@ -27,8 +27,8 @@
 
   ns.AddSearchPath("/odm/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
   ns.AddSearchPath("/vendor/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
-  ns.AddSearchPath("/system/${LIB}/vndk-sp-@{VNDK_VER}",
-                   AsanPath::WITH_DATA_ASAN);
+  ns.AddSearchPath("/apex/com.android.vndk.v@{VNDK_VER}/${LIB}",
+                   AsanPath::SAME_PATH);
   ns.AddSearchPath("/odm/${LIB}", AsanPath::WITH_DATA_ASAN);
   ns.AddSearchPath("/vendor/${LIB}", AsanPath::WITH_DATA_ASAN);
 
@@ -37,13 +37,12 @@
   ns.AddPermittedPath("/system/vendor/${LIB}", AsanPath::NONE);
   ns.AddPermittedPath("/data", AsanPath::SAME_PATH);
 
-  ns.CreateLink("default").AddSharedLib({"@{LLNDK_LIBRARIES}",
-                                         "@{SANITIZER_RUNTIME_LIBRARIES}",
-                                         "@{PRIVATE_LLNDK_LIBRARIES:}"});
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink(ctx.GetSystemNamespaceName())
+      .AddSharedLib({"@{LLNDK_LIBRARIES}", "@{PRIVATE_LLNDK_LIBRARIES:}"});
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/sphal.cc b/contents/namespace/sphal.cc
index 92df268..7a605f9 100644
--- a/contents/namespace/sphal.cc
+++ b/contents/namespace/sphal.cc
@@ -32,14 +32,13 @@
   ns.AddPermittedPath("/vendor/${LIB}", AsanPath::WITH_DATA_ASAN);
   ns.AddPermittedPath("/system/vendor/${LIB}", AsanPath::NONE);
 
-  ns.CreateLink("rs").AddSharedLib("libRS_internal.so");
-  ns.CreateLink("default").AddSharedLib(
-      {"@{LLNDK_LIBRARIES:}", "@{SANITIZER_RUNTIME_LIBRARIES:}"});
-  ns.CreateLink("vndk").AddSharedLib("@{VNDK_SAMEPROCESS_LIBRARIES:}");
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink("rs").AddSharedLib("libRS_internal.so");
+  ns.GetLink(ctx.GetSystemNamespaceName()).AddSharedLib("@{LLNDK_LIBRARIES:}");
+  ns.GetLink("vndk").AddSharedLib("@{VNDK_SAMEPROCESS_LIBRARIES:}");
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/system.cc b/contents/namespace/system.cc
index a8cabc2..841abbb 100644
--- a/contents/namespace/system.cc
+++ b/contents/namespace/system.cc
@@ -28,21 +28,20 @@
   ns.AddSearchPath("/@{SYSTEM_EXT:system_ext}/${LIB}", AsanPath::WITH_DATA_ASAN);
   ns.AddSearchPath("/@{PRODUCT:product}/${LIB}", AsanPath::WITH_DATA_ASAN);
 
-  ns.CreateLink("runtime").AddSharedLib(
+  ns.GetLink("art").AddSharedLib(
       {"libdexfile_external.so",
-       "libdexfile_external.so",
+       "libdexfiled_external.so",
        "libnativebridge.so",
        "libnativehelper.so",
        "libnativeloader.so",
        "libandroidicu.so",
-       // TODO(b/120786417 or b/134659294): libicuuc.so and libicui18n.so are
-       // kept for app compat.
+       // TODO(b/120786417 or b/134659294): libicuuc.so
+       // and libicui18n.so are kept for app compat.
        "libicui18n.so",
-       "libicuuc.so",
-       "@{SANITIZER_RUNTIME_LIBRARIES}"});
+       "libicuuc.so"});
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/systemdefault.cc b/contents/namespace/systemdefault.cc
index bf94280..03bee7c 100644
--- a/contents/namespace/systemdefault.cc
+++ b/contents/namespace/systemdefault.cc
@@ -14,26 +14,15 @@
  * limitations under the License.
  */
 
-#include "linkerconfig/namespacebuilder.h"
-
 #include "linkerconfig/environment.h"
 #include "linkerconfig/namespace.h"
+#include "linkerconfig/namespacebuilder.h"
 
 using android::linkerconfig::modules::AsanPath;
 using android::linkerconfig::modules::Namespace;
 
 namespace {
-const std::vector<std::string> kLibsFromRuntimeLegacy = {
-    "libart.so:libartd.so",
-    "libdexfile_external.so",
-    "libnativebridge.so",
-    "libnativehelper.so",
-    "libnativeloader.so",
-    "libandroidicu.so",
-    // TODO(b/122876336): Remove libpac.so once it's migrated to Webview
-    "libpac.so"};
-
-const std::vector<std::string> kLibsFromRuntime = {
+const std::vector<std::string> kLibsFromArt = {
     "libdexfile_external.so",
     "libdexfiled_external.so",
     "libnativebridge.so",
@@ -41,11 +30,11 @@
     "libnativeloader.so",
     "libandroidicu.so",
     "libpac.so",
-    "@{SANITIZER_RUNTIME_LIBRARIES}",
-    // TODO(b/120786417 or b/134659294): libicuuc.so and libicui18n.so are kept
-    // for app compat.
+    // TODO(b/120786417 or b/134659294): libicuuc.so
+    // and libicui18n.so are kept for app compat.
     "libicui18n.so",
-    "libicuuc.so"};
+    "libicuuc.so",
+};
 
 const std::vector<std::string> kPermittedPaths = {
     "/system/${LIB}/drm",
@@ -90,29 +79,30 @@
 namespace linkerconfig {
 namespace contents {
 Namespace BuildSystemDefaultNamespace([[maybe_unused]] const Context& ctx) {
-  bool is_legacy = android::linkerconfig::modules::IsLegacyDevice();
-  Namespace ns("default", /*is_isolated=*/!is_legacy,
+  bool is_fully_treblelized = ctx.IsDefaultConfig();
+  Namespace ns("default",
+               /*is_isolated=*/is_fully_treblelized,
                /*is_visible=*/true);
 
   ns.AddSearchPath("/system/${LIB}", AsanPath::WITH_DATA_ASAN);
   ns.AddSearchPath("/@{SYSTEM_EXT:system_ext}/${LIB}", AsanPath::WITH_DATA_ASAN);
   ns.AddSearchPath("/@{PRODUCT:product}/${LIB}", AsanPath::WITH_DATA_ASAN);
-  if (is_legacy) {
+  if (!is_fully_treblelized) {
     ns.AddSearchPath("/vendor/${LIB}", AsanPath::WITH_DATA_ASAN);
     ns.AddSearchPath("/odm/${LIB}", AsanPath::WITH_DATA_ASAN);
   }
 
-  if (!is_legacy) {
+  if (is_fully_treblelized) {
     BuildPermittedPath(ns);
   }
 
-  ns.CreateLink("runtime").AddSharedLib(is_legacy ? kLibsFromRuntimeLegacy
-                                                  : kLibsFromRuntime);
-  ns.CreateLink("resolv").AddSharedLib("libnetd_resolv.so");
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink("art").AddSharedLib(kLibsFromArt);
+
+  ns.GetLink("resolv").AddSharedLib("libnetd_resolv.so");
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/unrestricteddefault.cc b/contents/namespace/unrestricteddefault.cc
index 98f3680..11408a4 100644
--- a/contents/namespace/unrestricteddefault.cc
+++ b/contents/namespace/unrestricteddefault.cc
@@ -23,7 +23,7 @@
 using android::linkerconfig::modules::Namespace;
 
 namespace {
-const std::vector<std::string> kLibsFromRuntime = {
+const std::vector<std::string> kLibsFromArt = {
     "libdexfile_external.so",
     "libdexfiled_external.so",
     "libnativebridge.so",
@@ -34,8 +34,7 @@
     // TODO(b/120786417 or b/134659294): libicuuc.so and libicui18n.so are kept
     // for app compat.
     "libicui18n.so",
-    "libicuuc.so",
-    "@{SANITIZER_RUNTIME_LIBRARIES}"};
+    "libicuuc.so"};
 }  // namespace
 
 namespace android {
@@ -48,12 +47,12 @@
   ns.AddSearchPath("/odm/${LIB}", AsanPath::WITH_DATA_ASAN);
   ns.AddSearchPath("/vendor/${LIB}", AsanPath::WITH_DATA_ASAN);
 
-  ns.CreateLink("runtime").AddSharedLib(kLibsFromRuntime);
-  ns.CreateLink("resolv").AddSharedLib("libnetd_resolv.so");
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink("art").AddSharedLib(kLibsFromArt);
+  ns.GetLink("resolv").AddSharedLib("libnetd_resolv.so");
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/vendordefault.cc b/contents/namespace/vendordefault.cc
index 330df4d..efbfc03 100644
--- a/contents/namespace/vendordefault.cc
+++ b/contents/namespace/vendordefault.cc
@@ -14,24 +14,62 @@
  * limitations under the License.
  */
 
-#include "linkerconfig/namespacebuilder.h"
-
 #include "linkerconfig/environment.h"
+#include "linkerconfig/namespacebuilder.h"
 
 using android::linkerconfig::modules::AsanPath;
 using android::linkerconfig::modules::GetVendorVndkVersion;
 using android::linkerconfig::modules::Namespace;
 
+namespace {
+const std::vector<std::string> kVndkLiteArtLibs = {
+    "libdexfile_external.so",
+    "libdexfiled_external.so",
+    "libnativebridge.so",
+    "libnativehelper.so",
+    "libnativeloader.so",
+    // TODO(b/120786417 or b/134659294): libicuuc.so
+    // and libicui18n.so are kept for app compat.
+    "libicui18n.so",
+    "libicuuc.so",
+};
+}  // namespace
+
 namespace android {
 namespace linkerconfig {
 namespace contents {
 Namespace BuildVendorDefaultNamespace([[maybe_unused]] const Context& ctx) {
-  Namespace ns("default", /*is_isolated=*/true, /*is_visible=*/true);
+  bool is_vndklite = ctx.IsVndkliteConfig();
+
+  Namespace ns(
+      "default", /*is_isolated=*/!is_vndklite, /*is_visible=*/!is_vndklite);
 
   ns.AddSearchPath("/odm/${LIB}", AsanPath::WITH_DATA_ASAN);
-  ns.AddSearchPath("/vendor/${LIB}", AsanPath::WITH_DATA_ASAN);
+  // Allow loosen restriction between vndk and private platform libraries
+  if (is_vndklite) {
+    ns.AddSearchPath("/odm/${LIB}/vndk", AsanPath::WITH_DATA_ASAN);
+    ns.AddSearchPath("/odm/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
+  }
 
-  if (GetVendorVndkVersion() == "27") {
+  ns.AddSearchPath("/vendor/${LIB}", AsanPath::WITH_DATA_ASAN);
+  // Allow loosen restriction between vndk and private platform libraries
+  if (is_vndklite) {
+    ns.AddSearchPath("/vendor/${LIB}/vndk", AsanPath::WITH_DATA_ASAN);
+    ns.AddSearchPath("/vendor/${LIB}/vndk-sp", AsanPath::WITH_DATA_ASAN);
+  }
+
+  // VNDK-Lite devices require broader access from vendor to system/product partition
+  if (is_vndklite) {
+    ns.AddSearchPath("/system/${LIB}", AsanPath::WITH_DATA_ASAN);
+    ns.AddSearchPath("/@{SYSTEM_EXT:system_ext}/${LIB}",
+                     AsanPath::WITH_DATA_ASAN);
+    ns.AddSearchPath("/@{PRODUCT:product}/${LIB}", AsanPath::WITH_DATA_ASAN);
+    // Put system vndk at the last search order in vndk_lite for GSI
+    ns.AddSearchPath("/apex/com.android.vndk.v@{VNDK_VER}/${LIB}",
+                     AsanPath::SAME_PATH);
+  }
+
+  if (ctx.IsDefaultConfig() && GetVendorVndkVersion() == "27") {
     ns.AddSearchPath("/vendor/${LIB}/hw", AsanPath::WITH_DATA_ASAN);
     ns.AddSearchPath("/vendor/${LIB}/egl", AsanPath::WITH_DATA_ASAN);
   }
@@ -40,19 +78,21 @@
   ns.AddPermittedPath("/vendor", AsanPath::WITH_DATA_ASAN);
   ns.AddPermittedPath("/system/vendor", AsanPath::NONE);
 
-  ns.CreateLink("runtime").AddSharedLib("@{SANITIZER_RUNTIME_LIBRARIES}");
-  ns.CreateLink("system").AddSharedLib(
-      {"@{LLNDK_LIBRARIES}", "@{SANITIZER_RUNTIME_LIBRARIES}"});
-  ns.CreateLink("vndk").AddSharedLib(
-      {"@{VNDK_SAMEPROCESS_LIBRARIES}", "@{VNDK_CORE_LIBRARIES}"});
-  if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
-    ns.CreateLink("vndk_in_system")
-        .AddSharedLib("@{VNDK_USING_CORE_VARIANT_LIBRARIES}");
+  if (is_vndklite) {
+    ns.GetLink("art").AddSharedLib(kVndkLiteArtLibs);
+  } else {
+    ns.GetLink(ctx.GetSystemNamespaceName()).AddSharedLib("@{LLNDK_LIBRARIES}");
+    ns.GetLink("vndk").AddSharedLib(
+        {"@{VNDK_SAMEPROCESS_LIBRARIES}", "@{VNDK_CORE_LIBRARIES}"});
+    if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
+      ns.GetLink("vndk_in_system")
+          .AddSharedLib("@{VNDK_USING_CORE_VARIANT_LIBRARIES}");
+    }
   }
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/vndk.cc b/contents/namespace/vndk.cc
index d691b08..2ffeef7 100644
--- a/contents/namespace/vndk.cc
+++ b/contents/namespace/vndk.cc
@@ -26,20 +26,21 @@
 namespace contents {
 Namespace BuildVndkNamespace([[maybe_unused]] const Context& ctx) {
   bool is_system_section = ctx.IsSystemSection();
+  bool is_vndklite = ctx.IsVndkliteConfig();
   Namespace ns("vndk",
                /*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("/system/${LIB}/vndk-sp-@{VNDK_VER}",
-                   AsanPath::WITH_DATA_ASAN);
+  ns.AddSearchPath("/apex/com.android.vndk.v@{VNDK_VER}/${LIB}",
+                   AsanPath::SAME_PATH);
 
   if (!is_system_section) {
     ns.AddSearchPath("/odm/${LIB}/vndk", AsanPath::WITH_DATA_ASAN);
     ns.AddSearchPath("/vendor/${LIB}/vndk", AsanPath::WITH_DATA_ASAN);
-    ns.AddSearchPath("/system/${LIB}/vndk-@{VNDK_VER}",
-                     AsanPath::WITH_DATA_ASAN);
+    ns.AddSearchPath("/apex/com.android.vndk.v@{VNDK_VER}/${LIB}",
+                     AsanPath::SAME_PATH);
   }
 
   if (is_system_section) {
@@ -47,31 +48,33 @@
     ns.AddPermittedPath("/odm/${LIB}/egl", AsanPath::WITH_DATA_ASAN);
     ns.AddPermittedPath("/vendor/${LIB}/hw", AsanPath::WITH_DATA_ASAN);
     ns.AddPermittedPath("/vendor/${LIB}/egl", AsanPath::WITH_DATA_ASAN);
-    ns.AddPermittedPath("/system/vendor/${LIB}/hw", AsanPath::NONE);
+    if (!is_vndklite) {
+      ns.AddPermittedPath("/system/vendor/${LIB}/hw", AsanPath::NONE);
+    }
     ns.AddPermittedPath("/system/vendor/${LIB}/egl", AsanPath::NONE);
-    ns.AddPermittedPath("/system/${LIB}/vndk-sp-@{VNDK_VER}/hw",
-                        AsanPath::WITH_DATA_ASAN);
+    ns.AddPermittedPath("/apex/com.android.vndk.v@{VNDK_VER}/${LIB}/hw",
+                        AsanPath::SAME_PATH);
   }
 
-  ns.CreateLink(is_system_section ? "default" : "system")
-      .AddSharedLib({"@{LLNDK_LIBRARIES}", "@{SANITIZER_RUNTIME_LIBRARIES}"});
-  ns.CreateLink("runtime").AddSharedLib("@{SANITIZER_RUNTIME_LIBRARIES}");
+  ns.GetLink(ctx.GetSystemNamespaceName()).AddSharedLib({"@{LLNDK_LIBRARIES}"});
 
-  if (is_system_section) {
-    ns.CreateLink("sphal", true);
-  } else {
-    ns.CreateLink("default", true);
+  if (!is_vndklite) {
+    if (is_system_section) {
+      ns.GetLink("sphal").AllowAllSharedLibs();
+    } else {
+      ns.GetLink("default").AllowAllSharedLibs();
 
-    if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
-      ns.CreateLink("vndk_in_system")
-          .AddSharedLib("@{VNDK_USING_CORE_VARIANT_LIBRARIES}");
+      if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
+        ns.GetLink("vndk_in_system")
+            .AddSharedLib("@{VNDK_USING_CORE_VARIANT_LIBRARIES}");
+      }
     }
   }
 
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/namespace/vndkinsystem.cc b/contents/namespace/vndkinsystem.cc
index 965b750..87beb8b 100644
--- a/contents/namespace/vndkinsystem.cc
+++ b/contents/namespace/vndkinsystem.cc
@@ -36,14 +36,12 @@
     ns.AddWhitelisted("@{VNDK_USING_CORE_VARIANT_LIBRARIES}");
   }
 
-  ns.CreateLink("system").AddSharedLib(
-      {"@{LLNDK_LIBRARIES}", "@{SANITIZER_RUNTIME_LIBRARIES}"});
-  ns.CreateLink("vndk", true);
-  ns.CreateLink("runtime").AddSharedLib("@{SANITIZER_RUNTIME_LIBRARIES}");
-  ns.CreateLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
+  ns.GetLink(ctx.GetSystemNamespaceName()).AddSharedLib("@{LLNDK_LIBRARIES}");
+  ns.GetLink("vndk").AllowAllSharedLibs();
+  ns.GetLink("neuralnetworks").AddSharedLib("libneuralnetworks.so");
 
   return ns;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/section/legacy.cc b/contents/section/legacy.cc
index 76144df..cd448f6 100644
--- a/contents/section/legacy.cc
+++ b/contents/section/legacy.cc
@@ -16,6 +16,7 @@
 
 #include "linkerconfig/sectionbuilder.h"
 
+#include "linkerconfig/common.h"
 #include "linkerconfig/namespacebuilder.h"
 #include "linkerconfig/section.h"
 
@@ -31,14 +32,16 @@
   std::vector<Namespace> namespaces;
 
   namespaces.emplace_back(BuildSystemDefaultNamespace(ctx));
-  namespaces.emplace_back(BuildRuntimeNamespace(ctx));
+  namespaces.emplace_back(BuildArtNamespace(ctx));
   namespaces.emplace_back(BuildMediaNamespace(ctx));
   namespaces.emplace_back(BuildConscryptNamespace(ctx));
   namespaces.emplace_back(BuildResolvNamespace(ctx));
   namespaces.emplace_back(BuildNeuralNetworksNamespace(ctx));
 
-  return Section("legacy", std::move(namespaces));
+  Section section("legacy", std::move(namespaces));
+  AddStandardSystemLinks(ctx, &section);
+  return section;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/section/system.cc b/contents/section/system.cc
index df4c99c..da002de 100644
--- a/contents/section/system.cc
+++ b/contents/section/system.cc
@@ -16,6 +16,7 @@
 
 #include "linkerconfig/sectionbuilder.h"
 
+#include "linkerconfig/common.h"
 #include "linkerconfig/context.h"
 #include "linkerconfig/namespacebuilder.h"
 #include "linkerconfig/section.h"
@@ -32,7 +33,7 @@
   std::vector<Namespace> namespaces;
 
   namespaces.emplace_back(BuildSystemDefaultNamespace(ctx));
-  namespaces.emplace_back(BuildRuntimeNamespace(ctx));
+  namespaces.emplace_back(BuildArtNamespace(ctx));
   namespaces.emplace_back(BuildMediaNamespace(ctx));
   namespaces.emplace_back(BuildConscryptNamespace(ctx));
   namespaces.emplace_back(BuildResolvNamespace(ctx));
@@ -41,8 +42,10 @@
   namespaces.emplace_back(BuildVndkNamespace(ctx));
   namespaces.emplace_back(BuildNeuralNetworksNamespace(ctx));
 
-  return Section("system", std::move(namespaces));
+  Section section("system", std::move(namespaces));
+  AddStandardSystemLinks(ctx, &section);
+  return section;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/section/unrestricted.cc b/contents/section/unrestricted.cc
index efcc69a..ae57426 100644
--- a/contents/section/unrestricted.cc
+++ b/contents/section/unrestricted.cc
@@ -16,6 +16,7 @@
 
 #include "linkerconfig/sectionbuilder.h"
 
+#include "linkerconfig/common.h"
 #include "linkerconfig/environment.h"
 #include "linkerconfig/namespacebuilder.h"
 #include "linkerconfig/section.h"
@@ -32,14 +33,16 @@
   std::vector<Namespace> namespaces;
 
   namespaces.emplace_back(BuildUnrestrictedDefaultNamespace(ctx));
-  namespaces.emplace_back(BuildRuntimeNamespace(ctx));
+  namespaces.emplace_back(BuildArtNamespace(ctx));
   namespaces.emplace_back(BuildMediaNamespace(ctx));
   namespaces.emplace_back(BuildConscryptNamespace(ctx));
   namespaces.emplace_back(BuildResolvNamespace(ctx));
   namespaces.emplace_back(BuildNeuralNetworksNamespace(ctx));
 
-  return Section("unrestricted", std::move(namespaces));
+  Section section("unrestricted", std::move(namespaces));
+  AddStandardSystemLinks(ctx, &section);
+  return section;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/section/vendor.cc b/contents/section/vendor.cc
index ce264d1..7674433 100644
--- a/contents/section/vendor.cc
+++ b/contents/section/vendor.cc
@@ -16,6 +16,7 @@
 
 #include "linkerconfig/sectionbuilder.h"
 
+#include "linkerconfig/common.h"
 #include "linkerconfig/environment.h"
 #include "linkerconfig/namespacebuilder.h"
 #include "linkerconfig/section.h"
@@ -31,18 +32,27 @@
   ctx.SetCurrentSection(SectionType::Vendor);
   std::vector<Namespace> namespaces;
 
+  bool is_vndklite = ctx.IsVndkliteConfig();
+
   namespaces.emplace_back(BuildVendorDefaultNamespace(ctx));
-  namespaces.emplace_back(BuildRuntimeNamespace(ctx));
-  namespaces.emplace_back(BuildVndkNamespace(ctx));
-  namespaces.emplace_back(BuildSystemNamespace(ctx));
+  namespaces.emplace_back(BuildArtNamespace(ctx));
+  // VNDK-Lite devices does not contain VNDK and System namespace in vendor
+  // 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(BuildSystemNamespace(ctx));
+  }
   namespaces.emplace_back(BuildNeuralNetworksNamespace(ctx));
 
   if (android::linkerconfig::modules::IsVndkInSystemNamespace()) {
     namespaces.emplace_back(BuildVndkInSystemNamespace(ctx));
   }
 
-  return Section("vendor", std::move(namespaces));
+  Section section("vendor", std::move(namespaces));
+  AddStandardSystemLinks(ctx, &section);
+  return section;
 }
 }  // namespace contents
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/contents/tests/backward_compatibility/legacy_test.cc b/contents/tests/backward_compatibility/legacy_test.cc
index 22d5171..3afaf79 100644
--- a/contents/tests/backward_compatibility/legacy_test.cc
+++ b/contents/tests/backward_compatibility/legacy_test.cc
@@ -18,11 +18,13 @@
 
 #include "linkerconfig/legacy.h"
 #include "linkerconfig/variables.h"
+#include "testbase.h"
 
 using android::linkerconfig::modules::AsanPath;
 
-TEST(linkerconfig_legacy, backward_compatibility) {
-  android::linkerconfig::modules::Variables::AddValue("is_legacy", "true");
+TEST(linkerconfig_legacy_backward_compatibility, default_namespace) {
+  MockVariables();
+
   auto config = android::linkerconfig::contents::CreateLegacyConfiguration();
 
   auto legacy_section = config.GetSection("legacy");
diff --git a/contents/tests/backward_compatibility/testbase.h b/contents/tests/backward_compatibility/testbase.h
index affbc30..ccfed2e 100644
--- a/contents/tests/backward_compatibility/testbase.h
+++ b/contents/tests/backward_compatibility/testbase.h
@@ -34,4 +34,8 @@
                                                       "vndk_core_libraries");
   android::linkerconfig::modules::Variables::AddValue(
       "VNDK_USING_CORE_VARIANT_LIBRARIES", "vndk_using_core_variant_libraries");
+}
+
+inline void MockVnkdLite() {
+  android::linkerconfig::modules::Variables::AddValue("ro.vndk.lite", "true");
 }
\ No newline at end of file
diff --git a/contents/tests/backward_compatibility/vndklite_test.cc b/contents/tests/backward_compatibility/vndklite_test.cc
new file mode 100644
index 0000000..73b5aa7
--- /dev/null
+++ b/contents/tests/backward_compatibility/vndklite_test.cc
@@ -0,0 +1,138 @@
+/*
+ * 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 <gtest/gtest.h>
+
+#include "linkerconfig/baseconfig.h"
+#include "linkerconfig/variables.h"
+#include "testbase.h"
+
+using android::linkerconfig::modules::AsanPath;
+
+TEST(linkerconfig_vndklite_backward_compatibility, system_section) {
+  MockVariables();
+  MockVnkdLite();
+
+  auto config = android::linkerconfig::contents::CreateBaseConfiguration();
+
+  auto system_section = config.GetSection("system");
+  ASSERT_TRUE(system_section);
+
+  auto default_namespace = system_section->GetNamespace("default");
+  ASSERT_TRUE(default_namespace);
+
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/vendor/${LIB}",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/odm/${LIB}",
+                                                    AsanPath::WITH_DATA_ASAN));
+
+  auto sphal_namespace = system_section->GetNamespace("sphal");
+  ASSERT_TRUE(sphal_namespace);
+
+  EXPECT_TRUE(sphal_namespace->ContainsSearchPath("/odm/${LIB}",
+                                                  AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(sphal_namespace->ContainsSearchPath("/vendor/${LIB}",
+                                                  AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(
+      sphal_namespace->ContainsSearchPath("/vendor/${LIB}/hw", AsanPath::NONE));
+
+  EXPECT_TRUE(sphal_namespace->ContainsPermittedPath("/odm/${LIB}",
+                                                     AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(sphal_namespace->ContainsPermittedPath("/vendor/${LIB}",
+                                                     AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(sphal_namespace->ContainsPermittedPath("/system/vendor/${LIB}",
+                                                     AsanPath::NONE));
+
+  auto rs_namespace = system_section->GetNamespace("rs");
+  ASSERT_TRUE(rs_namespace);
+
+  EXPECT_TRUE(rs_namespace->ContainsSearchPath("/odm/${LIB}/vndk-sp",
+                                               AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(rs_namespace->ContainsSearchPath("/vendor/${LIB}/vndk-sp",
+                                               AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(rs_namespace->ContainsSearchPath("/odm/${LIB}",
+                                               AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(rs_namespace->ContainsSearchPath("/vendor/${LIB}",
+                                               AsanPath::WITH_DATA_ASAN));
+
+  EXPECT_TRUE(rs_namespace->ContainsPermittedPath("/odm/${LIB}",
+                                                  AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(rs_namespace->ContainsPermittedPath("/vendor/${LIB}",
+                                                  AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(rs_namespace->ContainsPermittedPath("/system/vendor/${LIB}",
+                                                  AsanPath::NONE));
+
+  auto vndk_namespace = system_section->GetNamespace("vndk");
+  ASSERT_TRUE(vndk_namespace);
+
+  EXPECT_TRUE(vndk_namespace->ContainsSearchPath("/odm/${LIB}/vndk-sp",
+                                                 AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(vndk_namespace->ContainsSearchPath("/vendor/${LIB}/vndk-sp",
+                                                 AsanPath::WITH_DATA_ASAN));
+
+  EXPECT_TRUE(vndk_namespace->ContainsPermittedPath("/odm/${LIB}/hw",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(vndk_namespace->ContainsPermittedPath("/odm/${LIB}/egl",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(vndk_namespace->ContainsPermittedPath("/vendor/${LIB}/hw",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(vndk_namespace->ContainsPermittedPath("/vendor/${LIB}/egl",
+                                                    AsanPath::WITH_DATA_ASAN));
+}
+
+TEST(linkerconfig_vndklite_backward_compatibility, vendor_section) {
+  MockVariables();
+  MockVnkdLite();
+
+  auto config = android::linkerconfig::contents::CreateBaseConfiguration();
+
+  auto vendor_section = config.GetSection("vendor");
+  ASSERT_TRUE(vendor_section);
+
+  auto default_namespace = vendor_section->GetNamespace("default");
+  ASSERT_TRUE(default_namespace);
+
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/odm/${LIB}",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/odm/${LIB}/vndk",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/odm/${LIB}/vndk-sp",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/vendor/${LIB}",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/vendor/${LIB}/vndk",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/vendor/${LIB}/vndk-sp",
+                                                    AsanPath::WITH_DATA_ASAN));
+}
+
+TEST(linkerconfig_vndklite_backward_compatibility, unrestricted_section) {
+  MockVariables();
+  MockVnkdLite();
+
+  auto config = android::linkerconfig::contents::CreateBaseConfiguration();
+
+  auto unrestricted_section = config.GetSection("unrestricted");
+  ASSERT_TRUE(unrestricted_section);
+
+  auto default_namespace = unrestricted_section->GetNamespace("default");
+  ASSERT_TRUE(default_namespace);
+
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/odm/${LIB}",
+                                                    AsanPath::WITH_DATA_ASAN));
+  EXPECT_TRUE(default_namespace->ContainsSearchPath("/vendor/${LIB}",
+                                                    AsanPath::WITH_DATA_ASAN));
+}
\ No newline at end of file
diff --git a/contents/tests/configuration/baseconfig_test.cc b/contents/tests/configuration/baseconfig_test.cc
index 231b087..c10003d 100644
--- a/contents/tests/configuration/baseconfig_test.cc
+++ b/contents/tests/configuration/baseconfig_test.cc
@@ -29,6 +29,19 @@
   VerifyConfiguration(config_writer.ToString());
 }
 
+TEST(linkerconfig_configuration_fulltest,
+     baseconfig_vndk_using_core_variant_test) {
+  MockGenericVariables();
+  MockVndkUsingCoreVariant();
+
+  auto base_config = android::linkerconfig::contents::CreateBaseConfiguration();
+  android::linkerconfig::modules::ConfigWriter config_writer;
+
+  base_config.WriteConfig(config_writer);
+
+  VerifyConfiguration(config_writer.ToString());
+}
+
 TEST(linkerconfig_configuration_fulltest, baseconfig_vndk_27_test) {
   MockGenericVariables();
   MockVndkVersion("27");
@@ -38,4 +51,17 @@
   base_config.WriteConfig(config_writer);
 
   VerifyConfiguration(config_writer.ToString());
+}
+
+TEST(linkerconfig_configuration_fulltest, vndklite_test) {
+  MockGenericVariables();
+  MockVnkdLite();
+
+  auto vndklite_config =
+      android::linkerconfig::contents::CreateBaseConfiguration();
+  android::linkerconfig::modules::ConfigWriter config_writer;
+
+  vndklite_config.WriteConfig(config_writer);
+
+  VerifyConfiguration(config_writer.ToString());
 }
\ No newline at end of file
diff --git a/contents/tests/configuration/include/mockenv.h b/contents/tests/configuration/include/mockenv.h
index f7e37f7..2815b4a 100644
--- a/contents/tests/configuration/include/mockenv.h
+++ b/contents/tests/configuration/include/mockenv.h
@@ -33,9 +33,18 @@
   android::linkerconfig::modules::Variables::AddValue("VNDK_CORE_LIBRARIES",
                                                       "vndk_core_libraries");
   android::linkerconfig::modules::Variables::AddValue(
-      "VNDK_USING_CORE_VARIANT_LIBRARIES", "vndk_using_core_variant_libraries");
+      "VNDK_USING_CORE_VARIANT_LIBRARIES", "");
 }
 
 inline void MockVndkVersion(std::string vndk_version) {
   android::linkerconfig::modules::Variables::AddValue("VNDK_VER", vndk_version);
+}
+
+inline void MockVndkUsingCoreVariant() {
+  android::linkerconfig::modules::Variables::AddValue(
+      "VNDK_USING_CORE_VARIANT_LIBRARIES", "vndk_using_core_variant_libraries");
+}
+
+inline void MockVnkdLite() {
+  android::linkerconfig::modules::Variables::AddValue("ro.vndk.lite", "true");
 }
\ No newline at end of file
diff --git a/main.cc b/main.cc
index a7dc090..a721485 100644
--- a/main.cc
+++ b/main.cc
@@ -15,12 +15,15 @@
  */
 
 #include <getopt.h>
+
 #include <cstring>
 #include <fstream>
 #include <iostream>
 #include <string>
 
 #include "linkerconfig/baseconfig.h"
+#include "linkerconfig/environment.h"
+#include "linkerconfig/legacy.h"
 #include "linkerconfig/log.h"
 #include "linkerconfig/variableloader.h"
 #include "linkerconfig/variables.h"
@@ -81,9 +84,9 @@
 }
 
 android::linkerconfig::modules::Configuration GetConfiguration() {
-  // TODO : Use legacy if needed
-
-  // TODO : Use vndk lite if needed
+  if (android::linkerconfig::modules::IsLegacyDevice()) {
+    return android::linkerconfig::contents::CreateLegacyConfiguration();
+  }
 
   // TODO : Use recovery if needed
 
diff --git a/modules/environment.cc b/modules/environment.cc
index d79c066..198e1e9 100644
--- a/modules/environment.cc
+++ b/modules/environment.cc
@@ -15,17 +15,18 @@
  */
 
 #include "linkerconfig/environment.h"
-
 #include "linkerconfig/variables.h"
 
 namespace android {
 namespace linkerconfig {
 namespace modules {
 bool IsLegacyDevice() {
-  // TODO : Implement
-  auto legacy_device = Variables::GetValue("is_legacy").value_or("false");
+  return !Variables::GetValue("ro.vndk.version").has_value() &&
+         !Variables::GetValue("ro.vndk.lite").has_value();
+}
 
-  return legacy_device == "true";
+bool IsVndkLiteDevice() {
+  return Variables::GetValue("ro.vndk.lite").value_or("") == "true";
 }
 
 bool IsVndkInSystemNamespace() {
diff --git a/modules/include/linkerconfig/environment.h b/modules/include/linkerconfig/environment.h
index 48c50a7..44eecae 100644
--- a/modules/include/linkerconfig/environment.h
+++ b/modules/include/linkerconfig/environment.h
@@ -20,6 +20,7 @@
 namespace linkerconfig {
 namespace modules {
 bool IsLegacyDevice();
+bool IsVndkLiteDevice();
 bool IsVndkInSystemNamespace();
 std::string GetVendorVndkVersion();
 }  // namespace modules
diff --git a/modules/include/linkerconfig/link.h b/modules/include/linkerconfig/link.h
index 25d9dd4..13c4093 100644
--- a/modules/include/linkerconfig/link.h
+++ b/modules/include/linkerconfig/link.h
@@ -27,40 +27,36 @@
 namespace modules {
 class Link {
  public:
-  Link(std::string origin_namespace, std::string target_namespace,
-       bool allow_all_shared_libs = false)
+  Link(std::string origin_namespace, std::string target_namespace)
       : origin_namespace_(std::move(origin_namespace)),
-        target_namespace_(std::move(target_namespace)),
-        allow_all_shared_libs_(allow_all_shared_libs) {
+        target_namespace_(std::move(target_namespace)) {
+    allow_all_shared_libs_ = false;
   }
   Link(const Link&) = delete;
   Link(Link&&) = default;
 
   template <typename T, typename... Args>
   void AddSharedLib(T&& lib_name, Args&&... lib_names);
-  void AddSharedLib(std::vector<std::string> lib_names);
+  void AddSharedLib(const std::vector<std::string>& lib_names);
+  void AllowAllSharedLibs();
   void WriteConfig(ConfigWriter& writer);
 
  private:
   const std::string origin_namespace_;
   const std::string target_namespace_;
-  const bool allow_all_shared_libs_;
   std::vector<std::string> shared_libs_;
+  bool allow_all_shared_libs_;
 };
 
 template <typename T, typename... Args>
 void Link::AddSharedLib(T&& lib_name, Args&&... lib_names) {
-  if (allow_all_shared_libs_) {
-    LOG(WARNING) << "Tried to add shared libraries to link from "
-                 << origin_namespace_ << " to " << target_namespace_
-                 << "while this link is allow_all_shared_libs";
-    return;
-  }
-  shared_libs_.push_back(std::forward<T>(lib_name));
-  if constexpr (sizeof...(Args) > 0) {
-    AddSharedLib(std::forward<Args>(lib_names)...);
+  if (!allow_all_shared_libs_) {
+    shared_libs_.push_back(std::forward<T>(lib_name));
+    if constexpr (sizeof...(Args) > 0) {
+      AddSharedLib(std::forward<Args>(lib_names)...);
+    }
   }
 }
 }  // namespace modules
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/modules/include/linkerconfig/namespace.h b/modules/include/linkerconfig/namespace.h
index fbd6b2e..9640b57 100644
--- a/modules/include/linkerconfig/namespace.h
+++ b/modules/include/linkerconfig/namespace.h
@@ -89,8 +89,11 @@
   //    namespace.xxx.asan.permitted.paths += /system/${LIB}
   void AddPermittedPath(const std::string& path,
                         AsanPath path_from_asan = AsanPath::SAME_PATH);
-  Link& CreateLink(const std::string& target_namespace,
-                   bool allow_all_shared_libs = false);
+
+  // Returns a link from this namespace to the given one. If one already exists
+  // it is returned, otherwise one is created.
+  Link& GetLink(const std::string& target_namespace);
+
   void WriteConfig(ConfigWriter& writer);
   void AddWhitelisted(const std::string& path);
 
@@ -115,4 +118,4 @@
 };
 }  // namespace modules
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/modules/include/linkerconfig/section.h b/modules/include/linkerconfig/section.h
index 5aecbe7..4d9aee3 100644
--- a/modules/include/linkerconfig/section.h
+++ b/modules/include/linkerconfig/section.h
@@ -40,13 +40,19 @@
   std::vector<std::string> GetBinaryPaths();
   std::string GetName();
 
-  // For test usage
   Namespace* GetNamespace(const std::string& namespace_name);
 
+  template <class _Function>
+  void ForEachNamespaces(_Function f) {
+    for (auto& ns : namespaces_) {
+      f(ns);
+    }
+  }
+
  private:
   const std::string name_;
   std::vector<Namespace> namespaces_;
 };
 }  // namespace modules
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/modules/link.cc b/modules/link.cc
index 70a32ad..19569ae 100644
--- a/modules/link.cc
+++ b/modules/link.cc
@@ -19,26 +19,40 @@
 namespace android {
 namespace linkerconfig {
 namespace modules {
+
+void Link::AddSharedLib(const std::vector<std::string>& lib_names) {
+  if (!allow_all_shared_libs_) {
+    shared_libs_.insert(shared_libs_.end(), lib_names.begin(), lib_names.end());
+  }
+}
+
+void Link::AllowAllSharedLibs() {
+  if (!allow_all_shared_libs_) {
+    shared_libs_.clear();
+    allow_all_shared_libs_ = true;
+  }
+}
+
 void Link::WriteConfig(ConfigWriter& writer) {
   writer.SetPrefix("namespace." + origin_namespace_ + ".link." +
                    target_namespace_);
   if (allow_all_shared_libs_) {
     writer.WriteLine(".allow_all_shared_libs = true");
-  } else {
+  } else if (!shared_libs_.empty()) {
     bool is_first = true;
 
     for (auto& lib_name : shared_libs_) {
-      writer.WriteLine(".shared_libs %s %s",
-                       is_first ? "=" : "+=", lib_name.c_str());
+      writer.WriteLine(
+          ".shared_libs %s %s", is_first ? "=" : "+=", lib_name.c_str());
       is_first = false;
     }
+  } else {
+    LOG(WARNING) << "Ignored empty shared libs link from " << origin_namespace_
+                 << " to " << target_namespace_;
   }
   writer.ResetPrefix();
 }
 
-void Link::AddSharedLib(std::vector<std::string> lib_names) {
-  shared_libs_.insert(shared_libs_.end(), lib_names.begin(), lib_names.end());
-}
 }  // namespace modules
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/modules/namespace.cc b/modules/namespace.cc
index bf98976..7588c84 100644
--- a/modules/namespace.cc
+++ b/modules/namespace.cc
@@ -50,17 +50,10 @@
   }
 }
 
-Link& Namespace::CreateLink(const std::string& target_namespace,
-                            bool allow_all_shared_libs) {
-  Link new_link(name_, target_namespace, allow_all_shared_libs);
-
-  if (links_.find(target_namespace) != links_.end()) {
-    LOG(INFO) << "Link to " << target_namespace
-              << " already exists. Overwriting link.";
-  }
-
-  links_.emplace(target_namespace, std::move(new_link));
-  return links_.find(target_namespace)->second;
+Link& Namespace::GetLink(const std::string& target_namespace) {
+  auto iter =
+      links_.try_emplace(target_namespace, name_, target_namespace).first;
+  return iter->second;
 }
 
 void Namespace::WriteConfig(ConfigWriter& writer) {
@@ -165,4 +158,4 @@
 }
 }  // namespace modules
 }  // namespace linkerconfig
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/modules/tests/link_test.cc b/modules/tests/link_test.cc
index a467ba4..c73e533 100644
--- a/modules/tests/link_test.cc
+++ b/modules/tests/link_test.cc
@@ -29,7 +29,8 @@
   android::linkerconfig::modules::ConfigWriter writer;
 
   auto link = std::make_shared<android::linkerconfig::modules::Link>(
-      "originalNamespace", "targetNamespace", true);
+      "originalNamespace", "targetNamespace");
+  link->AllowAllSharedLibs();
 
   link->WriteConfig(writer);
   auto config_text = writer.ToString();
@@ -49,4 +50,4 @@
   auto config_text = writer.ToString();
 
   ASSERT_EQ(config_text, kSharedLibsExpectedResult);
-}
\ No newline at end of file
+}
diff --git a/modules/tests/modules_testbase.h b/modules/tests/modules_testbase.h
index 7eca5a7..22f791a 100644
--- a/modules/tests/modules_testbase.h
+++ b/modules/tests/modules_testbase.h
@@ -36,9 +36,9 @@
                                           bool is_visible, std::string target_1,
                                           std::string target_2) {
   Namespace ns = CreateNamespaceWithPaths(name, is_isolated, is_visible);
-  auto& link = ns.CreateLink(target_1, false);
+  auto& link = ns.GetLink(target_1);
   link.AddSharedLib("lib1.so", "lib2.so", "lib3.so");
 
-  ns.CreateLink(target_2, true);
+  ns.GetLink(target_2).AllowAllSharedLibs();
   return ns;
-}
\ No newline at end of file
+}