ld.config for com.android.neuralnetworks APEX.

Makes updated libneuralnetworks.so in /apex/com.android.neuralnetworks/{LIB}
loadable from all relevant namespaces.

Test: Verified that right library is being loaded using lsof and
Test: verbose debug logs from bionic/ld.
Bug: 137320025
Change-Id: I38140bb9915a3f85f10456e15ed0f492dbdba802
diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp
index f7f972f..c22ce8a 100644
--- a/libnativeloader/library_namespaces.cpp
+++ b/libnativeloader/library_namespaces.cpp
@@ -43,6 +43,7 @@
 constexpr const char* kVendorNamespaceName = "sphal";
 constexpr const char* kVndkNamespaceName = "vndk";
 constexpr const char* kRuntimeNamespaceName = "runtime";
+constexpr const char* kNeuralNetworksNamespaceName = "neuralnetworks";
 
 // classloader-namespace is a linker namespace that is created for the loaded
 // app. To be specific, it is created for the app classloader. When
@@ -238,6 +239,14 @@
     }
   }
 
+  // Give access to NNAPI libraries (apex-updated LLNDK library).
+  auto nnapi_ns =
+      NativeLoaderNamespace::GetExportedNamespace(kNeuralNetworksNamespaceName, is_bridged);
+  if (!app_ns.Link(nnapi_ns, neuralnetworks_public_libraries())) {
+    *error_msg = app_ns.GetError();
+    return nullptr;
+  }
+
   // Give access to VNDK-SP libraries from the 'vndk' namespace.
   if (unbundled_vendor_or_product_app && !vndksp_libraries().empty()) {
     auto vndk_ns = NativeLoaderNamespace::GetExportedNamespace(kVndkNamespaceName, is_bridged);
diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp
index c205eb1..10e23fd 100644
--- a/libnativeloader/public_libraries.cpp
+++ b/libnativeloader/public_libraries.cpp
@@ -51,6 +51,8 @@
 
 constexpr const char* kRuntimeApexLibPath = "/apex/com.android.runtime/" LIB;
 
+constexpr const char* kNeuralNetworksApexPublicLibrary = "libneuralnetworks.so";
+
 // TODO(b/130388701): do we need this?
 std::string root_dir() {
   static const char* android_root_env = getenv("ANDROID_ROOT");
@@ -219,6 +221,12 @@
       sonames.erase(it);
     }
   }
+
+  // Remove the public libs in the nnapi namespace.
+  auto it = std::find(sonames.begin(), sonames.end(), kNeuralNetworksApexPublicLibrary);
+  if (it != sonames.end()) {
+    sonames.erase(it);
+  }
   return android::base::Join(sonames, ':');
 }
 
@@ -267,6 +275,10 @@
   return android::base::Join(sonames, ':');
 }
 
+static std::string InitNeuralNetworksPublicLibraries() {
+  return kNeuralNetworksApexPublicLibrary;
+}
+
 }  // namespace
 
 const std::string& default_public_libraries() {
@@ -289,6 +301,11 @@
   return list;
 }
 
+const std::string& neuralnetworks_public_libraries() {
+  static std::string list = InitNeuralNetworksPublicLibraries();
+  return list;
+}
+
 const std::string& llndk_libraries() {
   static std::string list = InitLlndkLibraries();
   return list;
diff --git a/libnativeloader/public_libraries.h b/libnativeloader/public_libraries.h
index 9b6dea8..9bb3366 100644
--- a/libnativeloader/public_libraries.h
+++ b/libnativeloader/public_libraries.h
@@ -26,6 +26,7 @@
 const std::string& runtime_public_libraries();
 const std::string& vendor_public_libraries();
 const std::string& extended_public_libraries();
+const std::string& neuralnetworks_public_libraries();
 const std::string& llndk_libraries();
 const std::string& vndksp_libraries();
 
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt
index ad14493..f0b1fd2 100644
--- a/rootdir/etc/ld.config.legacy.txt
+++ b/rootdir/etc/ld.config.legacy.txt
@@ -42,7 +42,7 @@
 # APEX related namespaces.
 ###############################################################################
 
-additional.namespaces = runtime,conscrypt,media,resolv
+additional.namespaces = runtime,conscrypt,media,neuralnetworks,resolv
 
 # Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
 # If a shared library or an executable requests a shared library that
@@ -51,8 +51,8 @@
 # shared library cannot be loaded from the runtime namespace either, the
 # dynamic linker tries to load the shared library from the resolv namespace.
 # Finally, if all attempts fail, the dynamic linker returns an error.
-namespace.default.links = runtime,resolv
-namespace.default.asan.links = runtime,resolv
+namespace.default.links = runtime,resolv,neuralnetworks
+namespace.default.asan.links = runtime,resolv,neuralnetworks
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -71,6 +71,9 @@
 # to be loaded in the default namespace.
 namespace.default.link.resolv.shared_libs = libnetd_resolv.so
 
+# LLNDK library moved into apex
+namespace.default.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "runtime" APEX namespace
 #
@@ -159,6 +162,27 @@
 namespace.resolv.link.default.shared_libs += libvndksupport.so
 
 ###############################################################################
+# "neuralnetworks" APEX namespace
+#
+# This namespace is for libraries within the NNAPI APEX.
+###############################################################################
+namespace.neuralnetworks.isolated = true
+namespace.neuralnetworks.visible = true
+
+namespace.neuralnetworks.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.asan.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.links = default
+namespace.neuralnetworks.link.default.shared_libs  = libc.so
+namespace.neuralnetworks.link.default.shared_libs += libcgrouprc.so
+namespace.neuralnetworks.link.default.shared_libs += libdl.so
+namespace.neuralnetworks.link.default.shared_libs += liblog.so
+namespace.neuralnetworks.link.default.shared_libs += libm.so
+namespace.neuralnetworks.link.default.shared_libs += libnativewindow.so
+namespace.neuralnetworks.link.default.shared_libs += libsync.so
+namespace.neuralnetworks.link.default.shared_libs += libvndksupport.so
+
+
+###############################################################################
 # Namespace config for binaries under /postinstall.
 # Only one default namespace is defined and it has no directories other than
 # /system/lib and /product/lib in the search paths. This is because linker
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index a6ea2ab..3321425 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -35,7 +35,7 @@
 dir.system = /data
 
 [system]
-additional.namespaces = runtime,conscrypt,media,resolv,sphal,vndk,rs
+additional.namespaces = runtime,conscrypt,media,neuralnetworks,resolv,sphal,vndk,rs
 
 ###############################################################################
 # "default" namespace
@@ -132,7 +132,7 @@
 # shared library cannot be loaded from the runtime namespace either, the
 # dynamic linker tries to load the shared library from the resolv namespace.
 # Finally, if all attempts fail, the dynamic linker returns an error.
-namespace.default.links = runtime,resolv
+namespace.default.links = runtime,resolv,neuralnetworks
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -152,6 +152,9 @@
 # to be loaded in the default namespace.
 namespace.default.link.resolv.shared_libs = libnetd_resolv.so
 
+# LLNDK library moved into apex
+namespace.default.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "runtime" APEX namespace
 #
@@ -185,13 +188,16 @@
 
 namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
 
-namespace.media.links = default
+namespace.media.links = default,neuralnetworks
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libcgrouprc.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.media.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "conscrypt" APEX namespace
 #
@@ -269,7 +275,7 @@
 # libs listed here can be used. Order is important here as the namespaces are
 # tried in this order. rs should be before vndk because both are capable
 # of loading libRS_internal.so
-namespace.sphal.links = rs,default,vndk
+namespace.sphal.links = rs,default,vndk,neuralnetworks
 
 # Renderscript gets separate namespace
 namespace.sphal.link.rs.shared_libs = libRS_internal.so
@@ -279,6 +285,10 @@
 
 namespace.sphal.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.sphal.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
+
 ###############################################################################
 # "rs" namespace
 #
@@ -318,7 +328,7 @@
 namespace.rs.asan.permitted.paths +=           /vendor/${LIB}
 namespace.rs.asan.permitted.paths += /data
 
-namespace.rs.links = default,vndk
+namespace.rs.links = default,vndk,neuralnetworks
 
 namespace.rs.link.default.shared_libs  = %LLNDK_LIBRARIES%
 namespace.rs.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -328,6 +338,10 @@
 
 namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.rs.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
+
 ###############################################################################
 # "vndk" namespace
 #
@@ -373,7 +387,7 @@
 # The "vndk" namespace links to "default" namespace for LLNDK libs and links to
 # "sphal" namespace for vendor libs.  The ordering matters.  The "default"
 # namespace has higher priority than the "sphal" namespace.
-namespace.vndk.links = default,sphal,runtime
+namespace.vndk.links = default,sphal,runtime,neuralnetworks
 
 # When these NDK libs are required inside this namespace, then it is redirected
 # to the default namespace. This is possible since their ABI is stable across
@@ -386,6 +400,28 @@
 # Allow VNDK-SP extensions to use vendor libraries
 namespace.vndk.link.sphal.allow_all_shared_libs = true
 
+# LLNDK library moved into apex
+namespace.vndk.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
+###############################################################################
+# "neuralnetworks" APEX namespace
+#
+# This namespace is for libraries within the NNAPI APEX.
+###############################################################################
+namespace.neuralnetworks.isolated = true
+namespace.neuralnetworks.visible = true
+
+namespace.neuralnetworks.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.asan.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.links = default
+namespace.neuralnetworks.link.default.shared_libs  = libc.so
+namespace.neuralnetworks.link.default.shared_libs += libcgrouprc.so
+namespace.neuralnetworks.link.default.shared_libs += libdl.so
+namespace.neuralnetworks.link.default.shared_libs += liblog.so
+namespace.neuralnetworks.link.default.shared_libs += libm.so
+namespace.neuralnetworks.link.default.shared_libs += libnativewindow.so
+namespace.neuralnetworks.link.default.shared_libs += libsync.so
+namespace.neuralnetworks.link.default.shared_libs += libvndksupport.so
 
 ###############################################################################
 # Namespace config for vendor processes. In O, no restriction is enforced for
@@ -394,7 +430,7 @@
 # (LL-NDK only) access.
 ###############################################################################
 [vendor]
-additional.namespaces = runtime,system,vndk%VNDK_IN_SYSTEM_NS%
+additional.namespaces = runtime,system,neuralnetworks,vndk%VNDK_IN_SYSTEM_NS%
 
 ###############################################################################
 # "default" namespace
@@ -435,7 +471,7 @@
 namespace.default.asan.permitted.paths += /data/asan/vendor
 namespace.default.asan.permitted.paths +=           /vendor
 
-namespace.default.links = system,vndk%VNDK_IN_SYSTEM_NS%,runtime
+namespace.default.links = system,vndk%VNDK_IN_SYSTEM_NS%,runtime,neuralnetworks
 namespace.default.link.runtime.shared_libs = %SANITIZER_RUNTIME_LIBRARIES%
 namespace.default.link.system.shared_libs  = %LLNDK_LIBRARIES%
 namespace.default.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -443,6 +479,9 @@
 namespace.default.link.vndk.shared_libs  = %VNDK_SAMEPROCESS_LIBRARIES%
 namespace.default.link.vndk.shared_libs += %VNDK_CORE_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.default.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "runtime" APEX namespace
 #
@@ -458,6 +497,7 @@
 # classloader-namespace for oat files, and tighten this up.
 namespace.runtime.link.system.allow_all_shared_libs = true
 
+
 ###############################################################################
 # "vndk" namespace
 #
@@ -491,7 +531,7 @@
 # Android releases.  The links here should be identical to that of the
 # 'vndk_in_system' namespace, except for the link between 'vndk' and
 # 'vndk_in_system'.
-namespace.vndk.links = system,default%VNDK_IN_SYSTEM_NS%,runtime
+namespace.vndk.links = system,default%VNDK_IN_SYSTEM_NS%,runtime,neuralnetworks
 
 namespace.vndk.link.system.shared_libs  = %LLNDK_LIBRARIES%
 namespace.vndk.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -502,6 +542,9 @@
 
 namespace.vndk.link.vndk_in_system.shared_libs = %VNDK_USING_CORE_VARIANT_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.vndk.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "system" namespace
 #
@@ -571,14 +614,34 @@
 #   1. 'vndk_in_system' needs to be freely linked back to 'vndk'.
 #   2. 'vndk_in_system' does not need to link to 'default', as any library that
 #      requires anything vendor would not be a vndk_in_system library.
-namespace.vndk_in_system.links = vndk,system,runtime
+namespace.vndk_in_system.links = vndk,system,runtime,neuralnetworks
 namespace.vndk_in_system.link.runtime.shared_libs = %SANITIZER_RUNTIME_LIBRARIES%
 
 namespace.vndk_in_system.link.system.shared_libs  = %LLNDK_LIBRARIES%
 namespace.vndk_in_system.link.system.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
 
 namespace.vndk_in_system.link.vndk.allow_all_shared_libs = true
+namespace.vndk_in_system.link.neuralnetworks.shared_libs = libneuralnetworks.so
 
+###############################################################################
+# "neuralnetworks" APEX namespace
+#
+# This namespace is for libraries within the NNAPI APEX.
+###############################################################################
+namespace.neuralnetworks.isolated = true
+namespace.neuralnetworks.visible = true
+
+namespace.neuralnetworks.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.asan.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.links = default
+namespace.neuralnetworks.link.default.shared_libs  = libc.so
+namespace.neuralnetworks.link.default.shared_libs += libcgrouprc.so
+namespace.neuralnetworks.link.default.shared_libs += libdl.so
+namespace.neuralnetworks.link.default.shared_libs += liblog.so
+namespace.neuralnetworks.link.default.shared_libs += libm.so
+namespace.neuralnetworks.link.default.shared_libs += libnativewindow.so
+namespace.neuralnetworks.link.default.shared_libs += libsync.so
+namespace.neuralnetworks.link.default.shared_libs += libvndksupport.so
 
 ###############################################################################
 # Namespace config for native tests that need access to both system and vendor
@@ -587,7 +650,7 @@
 # includes the requisite namespace setup for APEXes.
 ###############################################################################
 [unrestricted]
-additional.namespaces = runtime,media,conscrypt,resolv
+additional.namespaces = runtime,media,conscrypt,resolv,neuralnetworks
 
 # Visible to allow links to be created at runtime, e.g. through
 # android_link_namespaces in libnativeloader.
@@ -605,7 +668,7 @@
 namespace.default.asan.search.paths +=           /vendor/${LIB}
 
 # Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
-namespace.default.links = runtime,resolv
+namespace.default.links = runtime,resolv,neuralnetworks
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -621,6 +684,7 @@
 namespace.default.link.runtime.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
 
 namespace.default.link.resolv.shared_libs = libnetd_resolv.so
+namespace.default.link.neuralnetworks.shared_libs = libneuralnetworks.so
 
 ###############################################################################
 # "runtime" APEX namespace
@@ -653,12 +717,16 @@
 
 namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
 
-namespace.media.links = default
+namespace.media.links = default,neuralnetworks
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.media.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
+
 ###############################################################################
 # "conscrypt" APEX namespace
 #
@@ -694,6 +762,25 @@
 namespace.resolv.link.default.shared_libs += libbinder_ndk.so
 namespace.resolv.link.default.shared_libs += liblog.so
 
+###############################################################################
+# "neuralnetworks" APEX namespace
+#
+# This namespace is for libraries within the NNAPI APEX.
+###############################################################################
+namespace.neuralnetworks.isolated = true
+namespace.neuralnetworks.visible = true
+
+namespace.neuralnetworks.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.asan.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.links = default
+namespace.neuralnetworks.link.default.shared_libs  = libc.so
+namespace.neuralnetworks.link.default.shared_libs += libcgrouprc.so
+namespace.neuralnetworks.link.default.shared_libs += libdl.so
+namespace.neuralnetworks.link.default.shared_libs += liblog.so
+namespace.neuralnetworks.link.default.shared_libs += libm.so
+namespace.neuralnetworks.link.default.shared_libs += libnativewindow.so
+namespace.neuralnetworks.link.default.shared_libs += libsync.so
+namespace.neuralnetworks.link.default.shared_libs += libvndksupport.so
 
 ###############################################################################
 # Namespace config for binaries under /postinstall.
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index 69535a9..0bb60ab 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -35,7 +35,7 @@
 dir.system = /data
 
 [system]
-additional.namespaces = runtime,conscrypt,media,resolv,sphal,vndk,rs
+additional.namespaces = runtime,conscrypt,media,neuralnetworks,resolv,sphal,vndk,rs
 
 ###############################################################################
 # "default" namespace
@@ -72,7 +72,7 @@
 # shared library cannot be loaded from the runtime namespace either, the
 # dynamic linker tries to load the shared library from the resolv namespace.
 # Finally, if all attempts fail, the dynamic linker returns an error.
-namespace.default.links = runtime,resolv
+namespace.default.links = runtime,resolv,neuralnetworks
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -91,6 +91,9 @@
 # to be loaded in the default namespace.
 namespace.default.link.resolv.shared_libs = libnetd_resolv.so
 
+# LLNDK library moved into apex
+namespace.default.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "runtime" APEX namespace
 #
@@ -124,12 +127,15 @@
 
 namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
 
-namespace.media.links = default
+namespace.media.links = default,neuralnetworks
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.media.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "conscrypt" APEX namespace
 #
@@ -207,7 +213,7 @@
 # libs listed here can be used. Order is important here as the namespaces are
 # tried in this order. rs should be before vndk because both are capable
 # of loading libRS_internal.so
-namespace.sphal.links = rs,default,vndk
+namespace.sphal.links = rs,default,vndk,neuralnetworks
 
 # Renderscript gets separate namespace
 namespace.sphal.link.rs.shared_libs = libRS_internal.so
@@ -217,6 +223,9 @@
 
 namespace.sphal.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.sphal.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "rs" namespace
 #
@@ -256,7 +265,7 @@
 namespace.rs.asan.permitted.paths +=           /vendor/${LIB}
 namespace.rs.asan.permitted.paths += /data
 
-namespace.rs.links = default,vndk
+namespace.rs.links = default,vndk,neuralnetworks
 
 namespace.rs.link.default.shared_libs  = %LLNDK_LIBRARIES%
 namespace.rs.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
@@ -266,6 +275,9 @@
 
 namespace.rs.link.vndk.shared_libs = %VNDK_SAMEPROCESS_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.rs.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "vndk" namespace
 #
@@ -310,10 +322,31 @@
 # When these NDK libs are required inside this namespace, then it is redirected
 # to the default namespace. This is possible since their ABI is stable across
 # Android releases.
-namespace.vndk.links = default
+namespace.vndk.links = default,neuralnetworks
 
 namespace.vndk.link.default.shared_libs  = %LLNDK_LIBRARIES%
 namespace.vndk.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
+namespace.vndk.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
+###############################################################################
+# "neuralnetworks" APEX namespace
+#
+# This namespace is for libraries within the NNAPI APEX.
+###############################################################################
+namespace.neuralnetworks.isolated = true
+namespace.neuralnetworks.visible = true
+
+namespace.neuralnetworks.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.asan.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.links = default
+namespace.neuralnetworks.link.default.shared_libs  = libc.so
+namespace.neuralnetworks.link.default.shared_libs += libcgrouprc.so
+namespace.neuralnetworks.link.default.shared_libs += libdl.so
+namespace.neuralnetworks.link.default.shared_libs += liblog.so
+namespace.neuralnetworks.link.default.shared_libs += libm.so
+namespace.neuralnetworks.link.default.shared_libs += libnativewindow.so
+namespace.neuralnetworks.link.default.shared_libs += libsync.so
+namespace.neuralnetworks.link.default.shared_libs += libvndksupport.so
 
 
 ###############################################################################
@@ -323,7 +356,7 @@
 # (LL-NDK only) access.
 ###############################################################################
 [vendor]
-additional.namespaces = runtime
+additional.namespaces = runtime,neuralnetworks
 
 namespace.default.isolated = false
 
@@ -365,7 +398,7 @@
 namespace.default.asan.search.paths += /data/asan/system/${LIB}/vndk%VNDK_VER%
 namespace.default.asan.search.paths +=           /system/${LIB}/vndk%VNDK_VER%
 
-namespace.default.links = runtime
+namespace.default.links = runtime,neuralnetworks
 namespace.default.link.runtime.shared_libs  = libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
 # TODO(b/120786417 or b/134659294): libicuuc.so and libicui18n.so are kept for app compat.
@@ -377,6 +410,9 @@
 # Workaround for b/124772622
 namespace.default.link.runtime.shared_libs += libandroidicu.so
 
+# LLNDK library moved into apex
+namespace.default.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "runtime" APEX namespace
 #
@@ -393,13 +429,34 @@
 namespace.runtime.link.default.allow_all_shared_libs = true
 
 ###############################################################################
+# "neuralnetworks" APEX namespace
+#
+# This namespace is for libraries within the NNAPI APEX.
+###############################################################################
+namespace.neuralnetworks.isolated = true
+namespace.neuralnetworks.visible = true
+
+namespace.neuralnetworks.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.asan.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.links = default
+namespace.neuralnetworks.link.default.shared_libs  = libc.so
+namespace.neuralnetworks.link.default.shared_libs += libcgrouprc.so
+namespace.neuralnetworks.link.default.shared_libs += libdl.so
+namespace.neuralnetworks.link.default.shared_libs += liblog.so
+namespace.neuralnetworks.link.default.shared_libs += libm.so
+namespace.neuralnetworks.link.default.shared_libs += libnativewindow.so
+namespace.neuralnetworks.link.default.shared_libs += libsync.so
+namespace.neuralnetworks.link.default.shared_libs += libvndksupport.so
+
+
+###############################################################################
 # Namespace config for native tests that need access to both system and vendor
 # libraries. This replicates the default linker config (done by
 # init_default_namespace_no_config in bionic/linker/linker.cpp), except that it
 # includes the requisite namespace setup for APEXes.
 ###############################################################################
 [unrestricted]
-additional.namespaces = runtime,media,conscrypt,resolv
+additional.namespaces = runtime,media,conscrypt,resolv,neuralnetworks
 
 # Visible to allow links to be created at runtime, e.g. through
 # android_link_namespaces in libnativeloader.
@@ -417,7 +474,7 @@
 namespace.default.asan.search.paths +=           /vendor/${LIB}
 
 # Keep in sync with the "platform" namespace in art/build/apex/ld.config.txt.
-namespace.default.links = runtime,resolv
+namespace.default.links = runtime,resolv,neuralnetworks
 namespace.default.link.runtime.shared_libs  = libandroidicu.so
 namespace.default.link.runtime.shared_libs += libdexfile_external.so
 namespace.default.link.runtime.shared_libs += libdexfiled_external.so
@@ -434,6 +491,9 @@
 
 namespace.default.link.resolv.shared_libs = libnetd_resolv.so
 
+# LLNDK library moved into apex
+namespace.default.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "runtime" APEX namespace
 #
@@ -450,7 +510,6 @@
 namespace.runtime.links = default
 # TODO(b/130340935): Use a dynamically created linker namespace similar to
 # classloader-namespace for oat files, and tighten this up.
-namespace.runtime.link.default.allow_all_shared_libs = true
 
 ###############################################################################
 # "media" APEX namespace
@@ -465,12 +524,15 @@
 
 namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
 
-namespace.media.links = default
+namespace.media.links = default,neuralnetworks
 namespace.media.link.default.shared_libs  = %LLNDK_LIBRARIES%
 namespace.media.link.default.shared_libs += libbinder_ndk.so
 namespace.media.link.default.shared_libs += libmediametrics.so
 namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
 
+# LLNDK library moved into apex
+namespace.media.link.neuralnetworks.shared_libs = libneuralnetworks.so
+
 ###############################################################################
 # "conscrypt" APEX namespace
 #
@@ -506,6 +568,27 @@
 namespace.resolv.link.default.shared_libs += libbinder_ndk.so
 
 ###############################################################################
+# "neuralnetworks" APEX namespace
+#
+# This namespace is for libraries within the NNAPI APEX.
+###############################################################################
+namespace.neuralnetworks.isolated = true
+namespace.neuralnetworks.visible = true
+
+namespace.neuralnetworks.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.asan.search.paths = /apex/com.android.neuralnetworks/${LIB}
+namespace.neuralnetworks.links = default
+namespace.neuralnetworks.link.default.shared_libs  = libc.so
+namespace.neuralnetworks.link.default.shared_libs += libcgrouprc.so
+namespace.neuralnetworks.link.default.shared_libs += libdl.so
+namespace.neuralnetworks.link.default.shared_libs += liblog.so
+namespace.neuralnetworks.link.default.shared_libs += libm.so
+namespace.neuralnetworks.link.default.shared_libs += libnativewindow.so
+namespace.neuralnetworks.link.default.shared_libs += libsync.so
+namespace.neuralnetworks.link.default.shared_libs += libvndksupport.so
+
+
+###############################################################################
 # Namespace config for binaries under /postinstall.
 # Only default namespace is defined and default has no directories
 # other than /system/lib in the search paths. This is because linker calls
diff --git a/rootdir/update_and_install_ld_config.mk b/rootdir/update_and_install_ld_config.mk
index c949a4f..30537e7 100644
--- a/rootdir/update_and_install_ld_config.mk
+++ b/rootdir/update_and_install_ld_config.mk
@@ -40,6 +40,7 @@
 vndksp_libraries_file := $(library_lists_dir)/vndksp.libraries.$(vndk_version).txt
 vndkcore_libraries_file := $(library_lists_dir)/vndkcore.libraries.txt
 vndkprivate_libraries_file := $(library_lists_dir)/vndkprivate.libraries.txt
+llndk_moved_to_apex_libraries_file := $(library_lists_dir)/llndkinapex.libraries.txt
 ifeq ($(my_vndk_use_core_variant),true)
 vndk_using_core_variant_libraries_file := $(library_lists_dir)/vndk_using_core_variant.libraries.$(vndk_version).txt
 endif
@@ -65,6 +66,10 @@
   vndksp_libraries_list := $(VNDK_SAMEPROCESS_LIBRARIES)
 endif
 
+# LLNDK libraries that has been moved to an apex package and no longer are present on
+# /system image.
+llndk_libraries_moved_to_apex_list:=$(LLNDK_MOVED_TO_APEX_LIBRARIES)
+
 # $(1): list of libraries
 # $(2): output file to write the list of libraries to
 define write-libs-to-file
@@ -91,6 +96,14 @@
   cat $(PRIVATE_VNDK_PRIVATE_LIBRARIES_FILE) | xargs -n 1 -I privatelib bash -c "sed -i.bak 's/privatelib//' $(2)" && \
   sed -i.bak -e 's/::\+/:/g ; s/^:\+// ; s/:\+$$//' $(2) && \
   rm -f $(2).bak
+
+# # Given a file with a list of libs in "a:b:c" format, filter-out the LLNDK libraries migrated into apex file
+# # and write resulting list to a new file in "a:b:c" format
+ $(LOCAL_BUILT_MODULE): private-filter-out-llndk-in-apex-libs = \
+   for lib in $(PRIVATE_LLNDK_LIBRARIES_MOVED_TO_APEX_LIST); do sed -i.bak s/$$lib.so// $(1); done && \
+   sed -i.bak -e 's/::\+/:/g ; s/^:\+// ; s/:\+$$//' $(1) && \
+   rm -f $(1).bak
+
 $(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES_FILE := $(llndk_libraries_file)
 $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_SP_LIBRARIES_FILE := $(vndksp_libraries_file)
 $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_CORE_LIBRARIES_FILE := $(vndkcore_libraries_file)
@@ -100,6 +113,7 @@
 $(LOCAL_BUILT_MODULE): PRIVATE_INTERMEDIATES_DIR := $(intermediates_dir)
 $(LOCAL_BUILT_MODULE): PRIVATE_COMP_CHECK_SCRIPT := $(compatibility_check_script)
 $(LOCAL_BUILT_MODULE): PRIVATE_VNDK_VERSION_TAG := \#VNDK$(vndk_version)\#
+$(LOCAL_BUILT_MODULE): PRIVATE_LLNDK_LIBRARIES_MOVED_TO_APEX_LIST := $(llndk_libraries_moved_to_apex_list)
 deps := $(llndk_libraries_file) $(vndksp_libraries_file) $(vndkcore_libraries_file) \
   $(vndkprivate_libraries_file)
 ifeq ($(check_backward_compatibility),true)
@@ -118,6 +132,7 @@
 endif
 	@mkdir -p $(dir $@)
 	$(call private-filter-out-private-libs,$(PRIVATE_LLNDK_LIBRARIES_FILE),$(PRIVATE_INTERMEDIATES_DIR)/llndk_filtered)
+	$(call private-filter-out-llndk-in-apex-libs,$(PRIVATE_INTERMEDIATES_DIR)/llndk_filtered)
 	$(hide) sed -e "s?%LLNDK_LIBRARIES%?$$(cat $(PRIVATE_INTERMEDIATES_DIR)/llndk_filtered)?g" $< >$@
 	$(call private-filter-out-private-libs,$(PRIVATE_VNDK_SP_LIBRARIES_FILE),$(PRIVATE_INTERMEDIATES_DIR)/vndksp_filtered)
 	$(hide) sed -i.bak -e "s?%VNDK_SAMEPROCESS_LIBRARIES%?$$(cat $(PRIVATE_INTERMEDIATES_DIR)/vndksp_filtered)?g" $@
@@ -161,6 +176,7 @@
 intermediates_dir :=
 library_lists_dir :=
 llndk_libraries_file :=
+llndk_moved_to_apex_libraries_file :=
 vndksp_libraries_file :=
 vndkcore_libraries_file :=
 vndkprivate_libraries_file :=