Merge "Add LLNDK liblog stub library for the VNDK" into oc-dev
diff --git a/include/nativebridge/native_bridge.h b/include/nativebridge/native_bridge.h
index 45266de..929b8ae 100644
--- a/include/nativebridge/native_bridge.h
+++ b/include/nativebridge/native_bridge.h
@@ -116,14 +116,25 @@
 // Use NativeBridgeIsSupported() instead in non-namespace scenario.
 bool NativeBridgeIsPathSupported(const char* path);
 
-// Initializes public and anonymous namespace at native bridge side.
+// Initializes anonymous namespace.
+// NativeBridge's peer of android_init_anonymous_namespace() of dynamic linker.
+//
+// The anonymous namespace is used in the case when a NativeBridge implementation
+// cannot identify the caller of dlopen/dlsym which happens for the code not loaded
+// by dynamic linker; for example calls from the mono-compiled code.
 //
 // Starting with v3, NativeBridge has two scenarios: with/without namespace.
 // Should not use in non-namespace scenario.
-bool NativeBridgeInitNamespace(const char* public_ns_sonames,
-                               const char* anon_ns_library_path);
+bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames,
+                                        const char* anon_ns_library_path);
 
-// Create a namespace and pass the key of related namespaces to native bridge.
+// Create new namespace in which native libraries will be loaded.
+// NativeBridge's peer of android_create_namespace() of dynamic linker.
+//
+// The libraries in the namespace are searched by folowing order:
+// 1. ld_library_path (Think of this as namespace-local LD_LIBRARY_PATH)
+// 2. In directories specified by DT_RUNPATH of the "needed by" binary.
+// 3. deault_library_path (This of this as namespace-local default library path)
 //
 // Starting with v3, NativeBridge has two scenarios: with/without namespace.
 // Should not use in non-namespace scenario.
@@ -134,7 +145,17 @@
                                                        const char* permitted_when_isolated_path,
                                                        native_bridge_namespace_t* parent_ns);
 
+// Creates a link which shares some libraries from one namespace to another.
+// NativeBridge's peer of android_link_namespaces() of dynamic linker.
+//
+// Starting with v3, NativeBridge has two scenarios: with/without namespace.
+// Should not use in non-namespace scenario.
+bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_namespace_t* to,
+                                const char* shared_libs_sonames);
+
 // Load a shared library with namespace key that is supported by the native bridge.
+// NativeBridge's peer of android_dlopen_ext() of dynamic linker, only supports namespace
+// extension.
 //
 // Starting with v3, NativeBridge has two scenarios: with/without namespace.
 // Use NativeBridgeLoadLibrary() instead in non-namespace scenario.
@@ -152,7 +173,7 @@
   // Parameters:
   //   runtime_cbs [IN] the pointer to NativeBridgeRuntimeCallbacks.
   // Returns:
-  //   true iff initialization was successful.
+  //   true if initialization was successful.
   bool (*initialize)(const NativeBridgeRuntimeCallbacks* runtime_cbs, const char* private_dir,
                      const char* instruction_set);
 
@@ -194,10 +215,10 @@
   // instruction set.
   //
   // Parameters:
-  //    instruction_set [IN] the instruction set of the app
+  //   instruction_set [IN] the instruction set of the app
   // Returns:
-  //    NULL if not supported by native bridge.
-  //    Otherwise, return all environment values to be set after fork.
+  //   NULL if not supported by native bridge.
+  //   Otherwise, return all environment values to be set after fork.
   const struct NativeBridgeRuntimeValues* (*getAppEnv)(const char* instruction_set);
 
   // Added callbacks in version 2.
@@ -206,9 +227,9 @@
   // forwards- or backwards-compatible, and libnativebridge will then stop using it.
   //
   // Parameters:
-  //     bridge_version [IN] the version of libnativebridge.
+  //   bridge_version [IN] the version of libnativebridge.
   // Returns:
-  //     true iff the native bridge supports the given version of libnativebridge.
+  //   true if the native bridge supports the given version of libnativebridge.
   bool (*isCompatibleWith)(uint32_t bridge_version);
 
   // A callback to retrieve a native bridge's signal handler for the specified signal. The runtime
@@ -217,12 +238,12 @@
   // that will potentially lead to cycles.
   //
   // Parameters:
-  //     signal [IN] the signal for which the handler is asked for. Currently, only SIGSEGV is
+  //   signal [IN] the signal for which the handler is asked for. Currently, only SIGSEGV is
   //                 supported by the runtime.
   // Returns:
-  //     NULL if the native bridge doesn't use a handler or doesn't want it to be managed by the
-  //     runtime.
-  //     Otherwise, a pointer to the signal handler.
+  //   NULL if the native bridge doesn't use a handler or doesn't want it to be managed by the
+  //   runtime.
+  //   Otherwise, a pointer to the signal handler.
   NativeBridgeSignalHandlerFn (*getSignalHandler)(int signal);
 
   // Added callbacks in version 3.
@@ -231,7 +252,7 @@
   // to zero then the dynamic library is unloaded.
   //
   // Parameters:
-  //     handle [IN] the handler of a dynamic library.
+  //   handle [IN] the handler of a dynamic library.
   //
   // Returns:
   //   0 on success, and nonzero on error.
@@ -257,33 +278,36 @@
   // Use isSupported instead in non-namespace scenario.
   bool (*isPathSupported)(const char* library_path);
 
-  // Initializes anonymous namespace at native bridge side and pass the key of
-  // two namespaces(default and anonymous) owned by dynamic linker to native bridge.
+  // Initializes anonymous namespace at native bridge side.
+  // NativeBridge's peer of android_init_anonymous_namespace() of dynamic linker.
+  //
+  // The anonymous namespace is used in the case when a NativeBridge implementation
+  // cannot identify the caller of dlopen/dlsym which happens for the code not loaded
+  // by dynamic linker; for example calls from the mono-compiled code.
   //
   // Parameters:
-  //     public_ns_sonames [IN] the name of "public" libraries.
-  //     anon_ns_library_path [IN] the library search path of (anonymous) namespace.
+  //   public_ns_sonames [IN] the name of "public" libraries.
+  //   anon_ns_library_path [IN] the library search path of (anonymous) namespace.
   // Returns:
-  //     true if the pass is ok.
-  //     Otherwise, false.
+  //   true if the pass is ok.
+  //   Otherwise, false.
   //
   // Starting with v3, NativeBridge has two scenarios: with/without namespace.
   // Should not use in non-namespace scenario.
-  bool (*initNamespace)(const char* public_ns_sonames,
-                        const char* anon_ns_library_path);
+  bool (*initAnonymousNamespace)(const char* public_ns_sonames, const char* anon_ns_library_path);
 
-
-  // Create a namespace and pass the key of releated namespaces to native bridge.
+  // Create new namespace in which native libraries will be loaded.
+  // NativeBridge's peer of android_create_namespace() of dynamic linker.
   //
   // Parameters:
-  //     name [IN] the name of the namespace.
-  //     ld_library_path [IN] the first set of library search paths of the namespace.
-  //     default_library_path [IN] the second set of library search path of the namespace.
-  //     type [IN] the attribute of the namespace.
-  //     permitted_when_isolated_path [IN] the permitted path for isolated namespace(if it is).
-  //     parent_ns [IN] the pointer of the parent namespace to be inherited from.
+  //   name [IN] the name of the namespace.
+  //   ld_library_path [IN] the first set of library search paths of the namespace.
+  //   default_library_path [IN] the second set of library search path of the namespace.
+  //   type [IN] the attribute of the namespace.
+  //   permitted_when_isolated_path [IN] the permitted path for isolated namespace(if it is).
+  //   parent_ns [IN] the pointer of the parent namespace to be inherited from.
   // Returns:
-  //     native_bridge_namespace_t* for created namespace or nullptr in the case of error.
+  //   native_bridge_namespace_t* for created namespace or nullptr in the case of error.
   //
   // Starting with v3, NativeBridge has two scenarios: with/without namespace.
   // Should not use in non-namespace scenario.
@@ -294,7 +318,25 @@
                                                 const char* permitted_when_isolated_path,
                                                 native_bridge_namespace_t* parent_ns);
 
+  // Creates a link which shares some libraries from one namespace to another.
+  // NativeBridge's peer of android_link_namespaces() of dynamic linker.
+  //
+  // Parameters:
+  //   from [IN] the namespace where libraries are accessed.
+  //   to [IN] the namespace where libraries are loaded.
+  //   shared_libs_sonames [IN] the libraries to be shared.
+  //
+  // Returns:
+  //   Whether successed or not.
+  //
+  // Starting with v3, NativeBridge has two scenarios: with/without namespace.
+  // Should not use in non-namespace scenario.
+  bool (*linkNamespaces)(native_bridge_namespace_t* from, native_bridge_namespace_t* to,
+                         const char* shared_libs_sonames);
+
   // Load a shared library within a namespace.
+  // NativeBridge's peer of android_dlopen_ext() of dynamic linker, only supports namespace
+  // extension.
   //
   // Parameters:
   //   libpath [IN] path to the shared library
diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc
index 83f35b1..7976f67 100644
--- a/libnativebridge/native_bridge.cc
+++ b/libnativebridge/native_bridge.cc
@@ -573,17 +573,17 @@
   return false;
 }
 
-bool NativeBridgeInitNamespace(const char* public_ns_sonames,
-                               const char* anon_ns_library_path) {
-  if (NativeBridgeInitialized()) {
-    if (isCompatibleWith(NAMESPACE_VERSION)) {
-      return callbacks->initNamespace(public_ns_sonames, anon_ns_library_path);
-    } else {
-      ALOGE("not compatible with version %d, cannot init namespace", NAMESPACE_VERSION);
+bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames,
+                                        const char* anon_ns_library_path) {
+    if (NativeBridgeInitialized()) {
+        if (isCompatibleWith(NAMESPACE_VERSION)) {
+            return callbacks->initAnonymousNamespace(public_ns_sonames, anon_ns_library_path);
+        } else {
+            ALOGE("not compatible with version %d, cannot init namespace", NAMESPACE_VERSION);
+        }
     }
-  }
 
-  return false;
+    return false;
 }
 
 native_bridge_namespace_t* NativeBridgeCreateNamespace(const char* name,
@@ -608,6 +608,19 @@
   return nullptr;
 }
 
+bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_namespace_t* to,
+                                const char* shared_libs_sonames) {
+    if (NativeBridgeInitialized()) {
+        if (isCompatibleWith(NAMESPACE_VERSION)) {
+            return callbacks->linkNamespaces(from, to, shared_libs_sonames);
+        } else {
+            ALOGE("not compatible with version %d, cannot init namespace", NAMESPACE_VERSION);
+        }
+    }
+
+    return false;
+}
+
 void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns) {
   if (NativeBridgeInitialized()) {
     if (isCompatibleWith(NAMESPACE_VERSION)) {
diff --git a/libnativebridge/tests/Android.mk b/libnativebridge/tests/Android.mk
index 4c3e862..c9468f0 100644
--- a/libnativebridge/tests/Android.mk
+++ b/libnativebridge/tests/Android.mk
@@ -24,7 +24,7 @@
     NativeBridge3UnloadLibrary_test.cpp \
     NativeBridge3GetError_test.cpp \
     NativeBridge3IsPathSupported_test.cpp \
-    NativeBridge3InitNamespace_test.cpp \
+    NativeBridge3InitAnonymousNamespace_test.cpp \
     NativeBridge3CreateNamespace_test.cpp \
     NativeBridge3LoadLibraryExt_test.cpp
 
diff --git a/libnativebridge/tests/DummyNativeBridge3.cpp b/libnativebridge/tests/DummyNativeBridge3.cpp
index 13fce85..b0dd6d0 100644
--- a/libnativebridge/tests/DummyNativeBridge3.cpp
+++ b/libnativebridge/tests/DummyNativeBridge3.cpp
@@ -76,9 +76,9 @@
   return true;
 }
 
-extern "C" bool native_bridge3_initNamespace(const char* /* public_ns_sonames */,
-                                        const char* /* anon_ns_library_path */) {
-  return true;
+extern "C" bool native_bridge3_initAnonymousNamespace(const char* /* public_ns_sonames */,
+                                                      const char* /* anon_ns_library_path */) {
+    return true;
 }
 
 extern "C" android::native_bridge_namespace_t*
@@ -91,30 +91,34 @@
   return nullptr;
 }
 
+extern "C" bool native_bridge3_linkNamespaces(android::native_bridge_namespace_t* /* from */,
+                                              android::native_bridge_namespace_t* /* to */,
+                                              const char* /* shared_libs_soname */) {
+    return true;
+}
+
 extern "C" void* native_bridge3_loadLibraryExt(const char* /* libpath */,
                                                int /* flag */,
                                                android::native_bridge_namespace_t* /* ns */) {
   return nullptr;
 }
 
-
-android::NativeBridgeCallbacks NativeBridgeItf {
-  // v1
-  .version = 3,
-  .initialize = &native_bridge3_initialize,
-  .loadLibrary = &native_bridge3_loadLibrary,
-  .getTrampoline = &native_bridge3_getTrampoline,
-  .isSupported = &native_bridge3_isSupported,
-  .getAppEnv = &native_bridge3_getAppEnv,
-  // v2
-  .isCompatibleWith = &native_bridge3_isCompatibleWith,
-  .getSignalHandler = &native_bridge3_getSignalHandler,
-  // v3
-  .unloadLibrary = &native_bridge3_unloadLibrary,
-  .getError = &native_bridge3_getError,
-  .isPathSupported  = &native_bridge3_isPathSupported,
-  .initNamespace = &native_bridge3_initNamespace,
-  .createNamespace = &native_bridge3_createNamespace,
-  .loadLibraryExt = &native_bridge3_loadLibraryExt
-};
-
+android::NativeBridgeCallbacks NativeBridgeItf{
+    // v1
+    .version = 3,
+    .initialize = &native_bridge3_initialize,
+    .loadLibrary = &native_bridge3_loadLibrary,
+    .getTrampoline = &native_bridge3_getTrampoline,
+    .isSupported = &native_bridge3_isSupported,
+    .getAppEnv = &native_bridge3_getAppEnv,
+    // v2
+    .isCompatibleWith = &native_bridge3_isCompatibleWith,
+    .getSignalHandler = &native_bridge3_getSignalHandler,
+    // v3
+    .unloadLibrary = &native_bridge3_unloadLibrary,
+    .getError = &native_bridge3_getError,
+    .isPathSupported = &native_bridge3_isPathSupported,
+    .initAnonymousNamespace = &native_bridge3_initAnonymousNamespace,
+    .createNamespace = &native_bridge3_createNamespace,
+    .linkNamespaces = &native_bridge3_linkNamespaces,
+    .loadLibraryExt = &native_bridge3_loadLibraryExt};
diff --git a/libnativebridge/tests/NativeBridge3InitNamespace_test.cpp b/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp
similarity index 90%
rename from libnativebridge/tests/NativeBridge3InitNamespace_test.cpp
rename to libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp
index ae0fd2b..989a819 100644
--- a/libnativebridge/tests/NativeBridge3InitNamespace_test.cpp
+++ b/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp
@@ -20,7 +20,7 @@
 
 constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so";
 
-TEST_F(NativeBridgeTest, V3_InitNamespace) {
+TEST_F(NativeBridgeTest, V3_InitAnonymousNamespace) {
     // Init
     ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr));
     ASSERT_TRUE(NativeBridgeAvailable());
@@ -30,7 +30,7 @@
     ASSERT_TRUE(NativeBridgeAvailable());
 
     ASSERT_EQ(3U, NativeBridgeGetVersion());
-    ASSERT_EQ(true, NativeBridgeInitNamespace(nullptr, nullptr));
+    ASSERT_EQ(true, NativeBridgeInitAnonymousNamespace(nullptr, nullptr));
 
     // Clean-up code_cache
     ASSERT_EQ(0, rmdir(kCodeCache));
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index 74f2f1d..ebd6d4b 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -183,6 +183,11 @@
         return false;
       }
 
+      if (!NativeBridgeLinkNamespaces(ns, nullptr, public_libraries_.c_str())) {
+          *error_msg = NativeBridgeGetError();
+          return false;
+      }
+
       native_loader_ns = NativeLoaderNamespace(ns);
     }
 
@@ -324,10 +329,10 @@
 
     // and now initialize native bridge namespaces if necessary.
     if (NativeBridgeInitialized()) {
-      initialized_ = NativeBridgeInitNamespace(public_libraries_.c_str(),
-                                               is_native_bridge ? library_path : nullptr);
-      if (!initialized_) {
-        *error_msg = NativeBridgeGetError();
+        initialized_ = NativeBridgeInitAnonymousNamespace(
+            public_libraries_.c_str(), is_native_bridge ? library_path : nullptr);
+        if (!initialized_) {
+            *error_msg = NativeBridgeGetError();
       }
     }