2 * Copyright (C) 2015-2017 The Android-x86 Open Source Project
4 * by Chih-Wei Huang <cwhuang@linux.org.tw>
6 * Licensed under the GNU General Public License Version 2 or later.
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.gnu.org/licenses/gpl.html
14 #define LOG_TAG "libnb"
17 #include <cutils/log.h>
18 #include <cutils/properties.h>
19 #include "nativebridge/native_bridge.h"
30 static void *native_handle = nullptr;
32 static bool is_native_bridge_enabled()
34 return property_get_bool("persist.sys.nativebridge", 0);
37 static NativeBridgeCallbacks *get_callbacks()
39 static NativeBridgeCallbacks *callbacks = nullptr;
42 const char *libnb = "/system/lib"
48 native_handle = dlopen(libnb, RTLD_LAZY);
50 ALOGE("Unable to open %s", libnb);
54 callbacks = reinterpret_cast<NativeBridgeCallbacks *>(dlsym(native_handle, "NativeBridgeItf"));
55 ALOGI("Found %s version %u", libnb, callbacks ? callbacks->version : 0);
60 // NativeBridgeCallbacks implementations
61 static bool native_bridge2_initialize(const NativeBridgeRuntimeCallbacks *art_cbs,
62 const char *app_code_cache_dir,
65 LOGV("enter native_bridge2_initialize %s %s", app_code_cache_dir, isa);
66 if (is_native_bridge_enabled()) {
67 if (NativeBridgeCallbacks *cb = get_callbacks()) {
68 return cb->initialize(art_cbs, app_code_cache_dir, isa);
70 ALOGW("Native bridge is enabled but callbacks not found");
72 ALOGW("Native bridge is disabled");
77 static void *native_bridge2_loadLibrary(const char *libpath, int flag)
79 LOGV("enter native_bridge2_loadLibrary %s", libpath);
80 NativeBridgeCallbacks *cb = get_callbacks();
81 return cb ? cb->loadLibrary(libpath, flag) : nullptr;
84 static void *native_bridge2_getTrampoline(void *handle, const char *name,
85 const char* shorty, uint32_t len)
87 LOGV("enter native_bridge2_getTrampoline %s", name);
88 NativeBridgeCallbacks *cb = get_callbacks();
89 return cb ? cb->getTrampoline(handle, name, shorty, len) : nullptr;
92 static bool native_bridge2_isSupported(const char *libpath)
94 LOGV("enter native_bridge2_isSupported %s", libpath);
95 NativeBridgeCallbacks *cb = get_callbacks();
96 return cb ? cb->isSupported(libpath) : false;
99 static const struct NativeBridgeRuntimeValues *native_bridge2_getAppEnv(const char *abi)
101 LOGV("enter native_bridge2_getAppEnv %s", abi);
102 NativeBridgeCallbacks *cb = get_callbacks();
103 return cb ? cb->getAppEnv(abi) : nullptr;
106 static bool native_bridge2_isCompatibleWith(uint32_t version)
108 static uint32_t my_version = 0;
109 LOGV("enter native_bridge2_isCompatibleWith %u", version);
110 if (my_version == 0 && is_native_bridge_enabled()) {
111 if (NativeBridgeCallbacks *cb = get_callbacks()) {
112 my_version = cb->version;
115 // We have to claim a valid version before loading the real callbacks,
116 // otherwise native bridge will be disabled entirely
117 return version <= (my_version ? my_version : 3);
120 static NativeBridgeSignalHandlerFn native_bridge2_getSignalHandler(int signal)
122 LOGV("enter native_bridge2_getSignalHandler %d", signal);
123 NativeBridgeCallbacks *cb = get_callbacks();
124 return cb ? cb->getSignalHandler(signal) : nullptr;
127 static int native_bridge3_unloadLibrary(void *handle)
129 LOGV("enter native_bridge3_unloadLibrary %p", handle);
130 NativeBridgeCallbacks *cb = get_callbacks();
131 return cb ? cb->unloadLibrary(handle) : -1;
134 static const char *native_bridge3_getError()
136 LOGV("enter native_bridge3_getError");
137 NativeBridgeCallbacks *cb = get_callbacks();
138 return cb ? cb->getError() : "unknown";
141 static bool native_bridge3_isPathSupported(const char *path)
143 LOGV("enter native_bridge3_isPathSupported %s", path);
144 NativeBridgeCallbacks *cb = get_callbacks();
145 return cb && cb->isPathSupported(path);
148 static bool native_bridge3_initAnonymousNamespace(const char *public_ns_sonames,
149 const char *anon_ns_library_path)
151 LOGV("enter native_bridge3_initAnonymousNamespace %s, %s", public_ns_sonames, anon_ns_library_path);
152 NativeBridgeCallbacks *cb = get_callbacks();
153 return cb && cb->initAnonymousNamespace(public_ns_sonames, anon_ns_library_path);
156 static native_bridge_namespace_t *
157 native_bridge3_createNamespace(const char *name,
158 const char *ld_library_path,
159 const char *default_library_path,
161 const char *permitted_when_isolated_path,
162 native_bridge_namespace_t *parent_ns)
164 LOGV("enter native_bridge3_createNamespace %s, %s, %s, %s", name, ld_library_path, default_library_path, permitted_when_isolated_path);
165 NativeBridgeCallbacks *cb = get_callbacks();
166 return cb ? cb->createNamespace(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent_ns) : nullptr;
169 static bool native_bridge3_linkNamespaces(native_bridge_namespace_t *from,
170 native_bridge_namespace_t *to,
171 const char *shared_libs_soname)
173 LOGV("enter native_bridge3_linkNamespaces %s", shared_libs_soname);
174 NativeBridgeCallbacks *cb = get_callbacks();
175 return cb && cb->linkNamespaces(from, to, shared_libs_soname);
178 static void *native_bridge3_loadLibraryExt(const char *libpath,
180 native_bridge_namespace_t *ns)
182 LOGV("enter native_bridge3_loadLibraryExt %s, %d, %p", libpath, flag, ns);
183 NativeBridgeCallbacks *cb = get_callbacks();
184 void *result = cb ? cb->loadLibraryExt(libpath, flag, ns) : nullptr;
185 // void *result = cb ? cb->loadLibrary(libpath, flag) : nullptr;
186 LOGV("native_bridge3_loadLibraryExt: %p", result);
190 static native_bridge_namespace_t *native_bridge4_getVendorNamespace()
192 LOGV("enter native_bridge4_getVendorNamespace");
193 NativeBridgeCallbacks *cb = get_callbacks();
194 return cb ? cb->getVendorNamespace() : nullptr;
197 static void __attribute__ ((destructor)) on_dlclose()
200 dlclose(native_handle);
201 native_handle = nullptr;
207 NativeBridgeCallbacks NativeBridgeItf = {
210 .initialize = native_bridge2_initialize,
211 .loadLibrary = native_bridge2_loadLibrary,
212 .getTrampoline = native_bridge2_getTrampoline,
213 .isSupported = native_bridge2_isSupported,
214 .getAppEnv = native_bridge2_getAppEnv,
216 .isCompatibleWith = native_bridge2_isCompatibleWith,
217 .getSignalHandler = native_bridge2_getSignalHandler,
219 .unloadLibrary = native_bridge3_unloadLibrary,
220 .getError = native_bridge3_getError,
221 .isPathSupported = native_bridge3_isPathSupported,
222 .initAnonymousNamespace = native_bridge3_initAnonymousNamespace,
223 .createNamespace = native_bridge3_createNamespace,
224 .linkNamespaces = native_bridge3_linkNamespaces,
225 .loadLibraryExt = native_bridge3_loadLibraryExt,
227 .getVendorNamespace = native_bridge4_getVendorNamespace,
231 } // namespace android