Move to C API of libnativeloader.

Test: m
Bug: 119840313
Bug: 122710865
Change-Id: Id5b08ef5de0d38cb678a50e45d38dfb8107c4a1c
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index de7ea08..f231afa 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -52,7 +52,7 @@
 namespace android {
 
 #if defined(__ANDROID__)
-class NativeLoaderNamespace {
+struct NativeLoaderNamespace {
  public:
   NativeLoaderNamespace()
       : android_ns_(nullptr), native_bridge_ns_(nullptr) { }
@@ -151,14 +151,9 @@
  public:
   LibraryNamespaces() : initialized_(false) { }
 
-  NativeLoaderNamespace* Create(JNIEnv* env,
-                                uint32_t target_sdk_version,
-                                jobject class_loader,
-                                bool is_shared,
-                                bool is_for_vendor,
-                                jstring java_library_path,
-                                jstring java_permitted_path,
-                                std::string* error_msg) {
+  NativeLoaderNamespace* Create(JNIEnv* env, uint32_t target_sdk_version, jobject class_loader,
+                                bool is_shared, bool is_for_vendor, jstring java_library_path,
+                                jstring java_permitted_path, std::string* error_msg) {
     std::string library_path; // empty string by default.
 
     if (java_library_path != nullptr) {
@@ -628,13 +623,9 @@
   return nullptr;
 }
 
-void* OpenNativeLibrary(JNIEnv* env,
-                        int32_t target_sdk_version,
-                        const char* path,
-                        jobject class_loader,
-                        jstring library_path,
-                        bool* needs_native_bridge,
-                        std::string* error_msg) {
+void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path,
+                        jobject class_loader, jstring library_path, bool* needs_native_bridge,
+                        char** error_msg) {
 #if defined(__ANDROID__)
   UNUSED(target_sdk_version);
   if (class_loader == nullptr) {
@@ -652,19 +643,16 @@
   if ((ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader)) == nullptr) {
     // This is the case where the classloader was not created by ApplicationLoaders
     // In this case we create an isolated not-shared namespace for it.
-    if ((ns = g_namespaces->Create(env,
-                                   target_sdk_version,
-                                   class_loader,
-                                   false /* is_shared */,
-                                   false /* is_for_vendor */,
-                                   library_path,
-                                   nullptr,
-                                   error_msg)) == nullptr) {
+    std::string create_error_msg;
+    if ((ns = g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */,
+                                   false /* is_for_vendor */, library_path, nullptr,
+                                   &create_error_msg)) == nullptr) {
+      *error_msg = strdup(create_error_msg.c_str());
       return nullptr;
     }
   }
 
-  return OpenNativeLibrary(ns, path, needs_native_bridge, error_msg);
+  return OpenNativeLibraryInNamespace(ns, path, needs_native_bridge, error_msg);
 #else
   UNUSED(env, target_sdk_version, class_loader);
 
@@ -705,35 +693,40 @@
       if (handle != nullptr) {
         return handle;
       }
-      *error_msg = NativeBridgeGetError();
+      *error_msg = strdup(NativeBridgeGetError());
     } else {
-      *error_msg = dlerror();
+      *error_msg = strdup(dlerror());
     }
   }
   return nullptr;
 #endif
 }
 
-bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, std::string* error_msg) {
+bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) {
   bool success;
   if (needs_native_bridge) {
     success = (NativeBridgeUnloadLibrary(handle) == 0);
     if (!success) {
-      *error_msg = NativeBridgeGetError();
+      *error_msg = strdup(NativeBridgeGetError());
     }
   } else {
     success = (dlclose(handle) == 0);
     if (!success) {
-      *error_msg = dlerror();
+      *error_msg = strdup(dlerror());
     }
   }
 
   return success;
 }
 
+void NativeLoaderFreeErrorMessage(char* msg) {
+  // The error messages get allocated through strdup, so we must call free on them.
+  free(msg);
+}
+
 #if defined(__ANDROID__)
-void* OpenNativeLibrary(NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge,
-                        std::string* error_msg) {
+void* OpenNativeLibraryInNamespace(NativeLoaderNamespace* ns, const char* path,
+                                   bool* needs_native_bridge, char** error_msg) {
   if (ns->is_android_namespace()) {
     android_dlextinfo extinfo;
     extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE;
@@ -741,14 +734,14 @@
 
     void* handle = android_dlopen_ext(path, RTLD_NOW, &extinfo);
     if (handle == nullptr) {
-      *error_msg = dlerror();
+      *error_msg = strdup(dlerror());
     }
     *needs_native_bridge = false;
     return handle;
   } else {
     void* handle = NativeBridgeLoadLibraryExt(path, RTLD_NOW, ns->get_native_bridge_ns());
     if (handle == nullptr) {
-      *error_msg = NativeBridgeGetError();
+      *error_msg = strdup(NativeBridgeGetError());
     }
     *needs_native_bridge = true;
     return handle;