native_bridge.cc revision 4914fcd91bcd75400c0e023974158912f077464c
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "nativebridge/native_bridge.h" 18 19#include <dlfcn.h> 20#include <stdio.h> 21#include "utils/Mutex.h" 22 23 24namespace android { 25 26static Mutex native_bridge_lock("native bridge lock"); 27 28// The symbol name exposed by native-bridge with the type of NativeBridgeCallbacks. 29static constexpr const char* kNativeBridgeInterfaceSymbol = "NativeBridgeItf"; 30 31// The path of the library we are supposed to load. 32static const char* native_bridge_library_path = nullptr; 33 34// Whether a native bridge is available (loaded and ready). 35static bool available = false; 36// Whether we have already initialized (or tried to). 37static bool initialized = false; 38 39static NativeBridgeCallbacks* callbacks = nullptr; 40static const NativeBridgeRuntimeCallbacks* runtime_callbacks = nullptr; 41 42void SetupNativeBridge(const char* nb_library_path, 43 const NativeBridgeRuntimeCallbacks* runtime_cbs) { 44 Mutex::Autolock auto_lock(native_bridge_lock); 45 46 native_bridge_library_path = nb_library_path; 47 runtime_callbacks = runtime_cbs; 48 49 if (native_bridge_library_path == nullptr) { 50 initialized = true; 51 available = false; 52 } 53} 54 55static bool NativeBridgeInitialize() { 56 Mutex::Autolock auto_lock(native_bridge_lock); 57 58 if (initialized) { 59 // Somebody did it before. 60 return available; 61 } 62 63 available = false; 64 65 void* handle = dlopen(native_bridge_library_path, RTLD_LAZY); 66 if (handle != nullptr) { 67 callbacks = reinterpret_cast<NativeBridgeCallbacks*>(dlsym(handle, 68 kNativeBridgeInterfaceSymbol)); 69 70 if (callbacks != nullptr) { 71 available = callbacks->initialize(runtime_callbacks); 72 } 73 74 if (!available) { 75 dlclose(handle); 76 } 77 } 78 79 initialized = true; 80 81 return available; 82} 83 84void* NativeBridgeLoadLibrary(const char* libpath, int flag) { 85 if (NativeBridgeInitialize()) { 86 return callbacks->loadLibrary(libpath, flag); 87 } 88 return nullptr; 89} 90 91void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, 92 uint32_t len) { 93 if (NativeBridgeInitialize()) { 94 return callbacks->getTrampoline(handle, name, shorty, len); 95 } 96 return nullptr; 97} 98 99bool NativeBridgeIsSupported(const char* libpath) { 100 if (NativeBridgeInitialize()) { 101 return callbacks->isSupported(libpath); 102 } 103 return false; 104} 105 106}; // namespace android 107