[ART] Move to system/core native bridge library

Some cleanups on the way:
- move NativeBridgeRuntimeCallbacks from a global to a field
- rename native_bridge_library_string to the more suggestive
navtive_bridge_library_path
- clean up imports

Bug: 16884833

(cherry picked from commit I73aab8e212860ba5aee9444d801806d3da326a41)

Change-Id: I67f037ea81d2a4ede4294afd8b84b7640e534a13
diff --git a/runtime/Android.mk b/runtime/Android.mk
index bdecc7e..0876997 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -104,7 +104,7 @@
   mirror/string.cc \
   mirror/throwable.cc \
   monitor.cc \
-  native_bridge.cc \
+  native_bridge_art_interface.cc \
   native/dalvik_system_DexFile.cc \
   native/dalvik_system_VMDebug.cc \
   native/dalvik_system_VMRuntime.cc \
@@ -419,7 +419,7 @@
   LOCAL_C_INCLUDES += $$(ART_C_INCLUDES)
   LOCAL_C_INCLUDES += art/sigchainlib
 
-  LOCAL_SHARED_LIBRARIES += liblog libnativehelper
+  LOCAL_SHARED_LIBRARIES += liblog libnativehelper libnativebridge
   include external/libcxx/libcxx.mk
   LOCAL_SHARED_LIBRARIES += libbacktrace_libc++
   ifeq ($$(art_target_or_host),target)
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index e3341ce..2156ed1 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -42,7 +42,6 @@
 #include "mirror/object_array-inl.h"
 #include "mirror/string-inl.h"
 #include "mirror/throwable.h"
-#include "native_bridge.h"
 #include "parsed_options.h"
 #include "reflection.h"
 #include "runtime.h"
@@ -448,7 +447,7 @@
     if (m != nullptr) {
       shorty = m->GetShorty(&len);
     }
-    return NativeBridgeGetTrampoline(handle_, symbol_name.c_str(), shorty, len);
+    return android::NativeBridgeGetTrampoline(handle_, symbol_name.c_str(), shorty, len);
   }
 
   void VisitRoots(RootCallback* visitor, void* arg) {
@@ -3309,8 +3308,8 @@
   void* handle = dlopen(path_str, RTLD_LAZY);
   bool needs_native_bridge = false;
   if (handle == nullptr) {
-    if (NativeBridgeIsSupported(path_str)) {
-      handle = NativeBridgeLoadLibrary(path_str, RTLD_LAZY);
+    if (android::NativeBridgeIsSupported(path_str)) {
+      handle = android::NativeBridgeLoadLibrary(path_str, RTLD_LAZY);
       needs_native_bridge = true;
     }
   }
diff --git a/runtime/native_bridge.cc b/runtime/native_bridge.cc
deleted file mode 100644
index d0b516b..0000000
--- a/runtime/native_bridge.cc
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "native_bridge.h"
-
-#include <dlfcn.h>
-#include <stdio.h>
-#include "jni.h"
-
-#include "base/mutex.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/class-inl.h"
-#include "scoped_thread_state_change.h"
-#include "ScopedLocalRef.h"
-#include "thread.h"
-
-#ifdef HAVE_ANDROID_OS
-#include "cutils/properties.h"
-#endif
-
-
-namespace art {
-
-// The symbol name exposed by native-bridge with the type of NativeBridgeCallbacks.
-static constexpr const char* kNativeBridgeInterfaceSymbol = "NativeBridgeItf";
-
-// The library name we are supposed to load.
-static std::string native_bridge_library_string = "";
-
-// Whether a native bridge is available (loaded and ready).
-static bool available = false;
-// Whether we have already initialized (or tried to).
-static bool initialized = false;
-
-struct NativeBridgeCallbacks;
-static NativeBridgeCallbacks* callbacks = nullptr;
-
-// ART interfaces to native-bridge.
-struct NativeBridgeArtCallbacks {
-  // Get shorty of a Java method. The shorty is supposed to be persistent in memory.
-  //
-  // Parameters:
-  //   env [IN] pointer to JNIenv.
-  //   mid [IN] Java methodID.
-  // Returns:
-  //   short descriptor for method.
-  const char* (*getMethodShorty)(JNIEnv* env, jmethodID mid);
-
-  // Get number of native methods for specified class.
-  //
-  // Parameters:
-  //   env [IN] pointer to JNIenv.
-  //   clazz [IN] Java class object.
-  // Returns:
-  //   number of native methods.
-  uint32_t (*getNativeMethodCount)(JNIEnv* env, jclass clazz);
-
-  // Get at most 'method_count' native methods for specified class 'clazz'. Results are outputed
-  // via 'methods' [OUT]. The signature pointer in JNINativeMethod is reused as the method shorty.
-  //
-  // Parameters:
-  //   env [IN] pointer to JNIenv.
-  //   clazz [IN] Java class object.
-  //   methods [OUT] array of method with the name, shorty, and fnPtr.
-  //   method_count [IN] max number of elements in methods.
-  // Returns:
-  //   number of method it actually wrote to methods.
-  uint32_t (*getNativeMethods)(JNIEnv* env, jclass clazz, JNINativeMethod* methods,
-                               uint32_t method_count);
-};
-
-// Native-bridge interfaces to ART
-struct NativeBridgeCallbacks {
-  // Initialize native-bridge. Native-bridge's internal implementation must ensure MT safety and
-  // that the native-bridge is initialized only once. Thus it is OK to call this interface for an
-  // already initialized native-bridge.
-  //
-  // Parameters:
-  //   art_cbs [IN] the pointer to NativeBridgeArtCallbacks.
-  // Returns:
-  //   true iff initialization was successful.
-  bool (*initialize)(NativeBridgeArtCallbacks* art_cbs);
-
-  // Load a shared library that is supported by the native-bridge.
-  //
-  // Parameters:
-  //   libpath [IN] path to the shared library
-  //   flag [IN] the stardard RTLD_XXX defined in bionic dlfcn.h
-  // Returns:
-  //   The opaque handle of the shared library if sucessful, otherwise NULL
-  void* (*loadLibrary)(const char* libpath, int flag);
-
-  // Get a native-bridge trampoline for specified native method. The trampoline has same
-  // sigature as the native method.
-  //
-  // Parameters:
-  //   handle [IN] the handle returned from loadLibrary
-  //   shorty [IN] short descriptor of native method
-  //   len [IN] length of shorty
-  // Returns:
-  //   address of trampoline if successful, otherwise NULL
-  void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len);
-
-  // Check whether native library is valid and is for an ABI that is supported by native-bridge.
-  //
-  // Parameters:
-  //   libpath [IN] path to the shared library
-  // Returns:
-  //   TRUE if library is supported by native-bridge, FALSE otherwise
-  bool (*isSupported)(const char* libpath);
-};
-
-static const char* GetMethodShorty(JNIEnv* env, jmethodID mid) {
-  ScopedObjectAccess soa(env);
-  StackHandleScope<1> scope(soa.Self());
-  mirror::ArtMethod* m = soa.DecodeMethod(mid);
-  MethodHelper mh(scope.NewHandle(m));
-  return mh.GetShorty();
-}
-
-static uint32_t GetNativeMethodCount(JNIEnv* env, jclass clazz) {
-  if (clazz == nullptr)
-    return 0;
-
-  ScopedObjectAccess soa(env);
-  mirror::Class* c = soa.Decode<mirror::Class*>(clazz);
-
-  uint32_t native_method_count = 0;
-  for (uint32_t i = 0; i < c->NumDirectMethods(); ++i) {
-    mirror::ArtMethod* m = c->GetDirectMethod(i);
-    if (m->IsNative()) {
-      native_method_count++;
-    }
-  }
-  for (uint32_t i = 0; i < c->NumVirtualMethods(); ++i) {
-    mirror::ArtMethod* m = c->GetVirtualMethod(i);
-    if (m->IsNative()) {
-      native_method_count++;
-    }
-  }
-  return native_method_count;
-}
-
-static uint32_t GetNativeMethods(JNIEnv* env, jclass clazz, JNINativeMethod* methods,
-                               uint32_t method_count) {
-  if ((clazz == nullptr) || (methods == nullptr)) {
-    return 0;
-  }
-  ScopedObjectAccess soa(env);
-  mirror::Class* c = soa.Decode<mirror::Class*>(clazz);
-
-  uint32_t count = 0;
-  for (uint32_t i = 0; i < c->NumDirectMethods(); ++i) {
-    mirror::ArtMethod* m = c->GetDirectMethod(i);
-    if (m->IsNative()) {
-      if (count < method_count) {
-        methods[count].name = m->GetName();
-        methods[count].signature = m->GetShorty();
-        methods[count].fnPtr = const_cast<void*>(m->GetNativeMethod());
-        count++;
-      } else {
-        LOG(WARNING) << "Output native method array too small. Skipping " << PrettyMethod(m);
-      }
-    }
-  }
-  for (uint32_t i = 0; i < c->NumVirtualMethods(); ++i) {
-    mirror::ArtMethod* m = c->GetVirtualMethod(i);
-    if (m->IsNative()) {
-      if (count < method_count) {
-        methods[count].name = m->GetName();
-        methods[count].signature = m->GetShorty();
-        methods[count].fnPtr = const_cast<void*>(m->GetNativeMethod());
-        count++;
-      } else {
-        LOG(WARNING) << "Output native method array too small. Skipping " << PrettyMethod(m);
-      }
-    }
-  }
-  return count;
-}
-
-static NativeBridgeArtCallbacks NativeBridgeArtItf = {
-  GetMethodShorty,
-  GetNativeMethodCount,
-  GetNativeMethods
-};
-
-void SetNativeBridgeLibraryString(const std::string& nb_library_string) {
-  // This is called when the runtime starts and nothing is working concurrently
-  // so we don't need a lock here.
-
-  native_bridge_library_string = nb_library_string;
-
-  if (native_bridge_library_string.empty()) {
-    initialized = true;
-    available = false;
-  }
-}
-
-static bool NativeBridgeInitialize() {
-  // TODO: Missing annotalysis static lock ordering of DEFAULT_MUTEX_ACQUIRED, place lock into
-  // global order or remove.
-  static Mutex lock("native bridge lock");
-  MutexLock mu(Thread::Current(), lock);
-
-  if (initialized) {
-    // Somebody did it before.
-    return available;
-  }
-
-  available = false;
-
-  void* handle = dlopen(native_bridge_library_string.c_str(), RTLD_LAZY);
-  if (handle != nullptr) {
-    callbacks = reinterpret_cast<NativeBridgeCallbacks*>(dlsym(handle,
-                                                               kNativeBridgeInterfaceSymbol));
-
-    if (callbacks != nullptr) {
-      available = callbacks->initialize(&NativeBridgeArtItf);
-    }
-
-    if (!available) {
-      dlclose(handle);
-    }
-  }
-
-  initialized = true;
-
-  return available;
-}
-
-void* NativeBridgeLoadLibrary(const char* libpath, int flag) {
-  if (NativeBridgeInitialize()) {
-    return callbacks->loadLibrary(libpath, flag);
-  }
-  return nullptr;
-}
-
-void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty,
-                                  uint32_t len) {
-  if (NativeBridgeInitialize()) {
-    return callbacks->getTrampoline(handle, name, shorty, len);
-  }
-  return nullptr;
-}
-
-bool NativeBridgeIsSupported(const char* libpath) {
-  if (NativeBridgeInitialize()) {
-    return callbacks->isSupported(libpath);
-  }
-  return false;
-}
-
-};  // namespace art
diff --git a/runtime/native_bridge.h b/runtime/native_bridge.h
deleted file mode 100644
index be647fc..0000000
--- a/runtime/native_bridge.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_NATIVE_BRIDGE_H_
-#define ART_RUNTIME_NATIVE_BRIDGE_H_
-
-#include <string>
-
-namespace art {
-
-// Initialize the native bridge, if any. Should be called by Runtime::Init(). An empty string
-// signals that we do not want to load a native bridge.
-void SetNativeBridgeLibraryString(const std::string& native_bridge_library_string);
-
-// Load a shared library that is supported by the native-bridge.
-void* NativeBridgeLoadLibrary(const char* libpath, int flag);
-
-// Get a native-bridge trampoline for specified native method.
-void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len);
-
-// True if native library is valid and is for an ABI that is supported by native-bridge.
-bool NativeBridgeIsSupported(const char* libpath);
-
-};  // namespace art
-
-#endif  // ART_RUNTIME_NATIVE_BRIDGE_H_
diff --git a/runtime/native_bridge_art_interface.cc b/runtime/native_bridge_art_interface.cc
new file mode 100644
index 0000000..453c92f
--- /dev/null
+++ b/runtime/native_bridge_art_interface.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "native_bridge_art_interface.h"
+
+#include "mirror/art_method-inl.h"
+#include "mirror/class-inl.h"
+#include "scoped_thread_state_change.h"
+
+namespace art {
+
+const char* GetMethodShorty(JNIEnv* env, jmethodID mid) {
+  ScopedObjectAccess soa(env);
+  StackHandleScope<1> scope(soa.Self());
+  mirror::ArtMethod* m = soa.DecodeMethod(mid);
+  MethodHelper mh(scope.NewHandle(m));
+  return mh.GetShorty();
+}
+
+uint32_t GetNativeMethodCount(JNIEnv* env, jclass clazz) {
+  if (clazz == nullptr)
+    return 0;
+
+  ScopedObjectAccess soa(env);
+  mirror::Class* c = soa.Decode<mirror::Class*>(clazz);
+
+  uint32_t native_method_count = 0;
+  for (uint32_t i = 0; i < c->NumDirectMethods(); ++i) {
+    mirror::ArtMethod* m = c->GetDirectMethod(i);
+    if (m->IsNative()) {
+      native_method_count++;
+    }
+  }
+  for (uint32_t i = 0; i < c->NumVirtualMethods(); ++i) {
+    mirror::ArtMethod* m = c->GetVirtualMethod(i);
+    if (m->IsNative()) {
+      native_method_count++;
+    }
+  }
+  return native_method_count;
+}
+
+uint32_t GetNativeMethods(JNIEnv* env, jclass clazz, JNINativeMethod* methods,
+                          uint32_t method_count) {
+  if ((clazz == nullptr) || (methods == nullptr)) {
+    return 0;
+  }
+  ScopedObjectAccess soa(env);
+  mirror::Class* c = soa.Decode<mirror::Class*>(clazz);
+
+  uint32_t count = 0;
+  for (uint32_t i = 0; i < c->NumDirectMethods(); ++i) {
+    mirror::ArtMethod* m = c->GetDirectMethod(i);
+    if (m->IsNative()) {
+      if (count < method_count) {
+        methods[count].name = m->GetName();
+        methods[count].signature = m->GetShorty();
+        methods[count].fnPtr = const_cast<void*>(m->GetNativeMethod());
+        count++;
+      } else {
+        LOG(WARNING) << "Output native method array too small. Skipping " << PrettyMethod(m);
+      }
+    }
+  }
+  for (uint32_t i = 0; i < c->NumVirtualMethods(); ++i) {
+    mirror::ArtMethod* m = c->GetVirtualMethod(i);
+    if (m->IsNative()) {
+      if (count < method_count) {
+        methods[count].name = m->GetName();
+        methods[count].signature = m->GetShorty();
+        methods[count].fnPtr = const_cast<void*>(m->GetNativeMethod());
+        count++;
+      } else {
+        LOG(WARNING) << "Output native method array too small. Skipping " << PrettyMethod(m);
+      }
+    }
+  }
+  return count;
+}
+
+};  // namespace art
diff --git a/runtime/native_bridge_art_interface.h b/runtime/native_bridge_art_interface.h
new file mode 100644
index 0000000..08735c8
--- /dev/null
+++ b/runtime/native_bridge_art_interface.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_NATIVE_BRIDGE_ART_INTERFACE_H_
+#define ART_RUNTIME_NATIVE_BRIDGE_ART_INTERFACE_H_
+
+#include <jni.h>
+#include <stdint.h>
+
+namespace art {
+
+const char* GetMethodShorty(JNIEnv* env, jmethodID mid);
+
+uint32_t GetNativeMethodCount(JNIEnv* env, jclass clazz);
+
+uint32_t GetNativeMethods(JNIEnv* env, jclass clazz, JNINativeMethod* methods,
+                          uint32_t method_count);
+
+};  // namespace art
+
+#endif  // ART_RUNTIME_NATIVE_BRIDGE_ART_INTERFACE_H_
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 36ad56b..244f3c4 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -605,7 +605,7 @@
         return false;
       }
     } else if (StartsWith(option, "-XX:NativeBridge=")) {
-      if (!ParseStringAfterChar(option, '=', &native_bridge_library_string_)) {
+      if (!ParseStringAfterChar(option, '=', &native_bridge_library_path_)) {
         return false;
       }
     } else if (StartsWith(option, "-ea") ||
diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h
index 3dbe26f..1cb9b3a 100644
--- a/runtime/parsed_options.h
+++ b/runtime/parsed_options.h
@@ -45,7 +45,7 @@
   std::string image_;
   bool check_jni_;
   std::string jni_trace_;
-  std::string native_bridge_library_string_;
+  std::string native_bridge_library_path_;
   CompilerCallbacks* compiler_callbacks_;
   bool is_zygote_;
   bool must_relocate_;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 6a3673c..eeddac1 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -63,7 +63,7 @@
 #include "mirror/stack_trace_element.h"
 #include "mirror/throwable.h"
 #include "monitor.h"
-#include "native_bridge.h"
+#include "native_bridge_art_interface.h"
 #include "parsed_options.h"
 #include "oat_file.h"
 #include "quick/quick_method_frame_info.h"
@@ -142,7 +142,8 @@
       target_sdk_version_(0),
       implicit_null_checks_(false),
       implicit_so_checks_(false),
-      implicit_suspend_checks_(false) {
+      implicit_suspend_checks_(false),
+      native_bridge_art_callbacks_({GetMethodShorty, GetNativeMethodCount, GetNativeMethods}) {
 }
 
 Runtime::~Runtime() {
@@ -708,7 +709,11 @@
   self->ClearException();
 
   // Look for a native bridge.
-  SetNativeBridgeLibraryString(options->native_bridge_library_string_);
+  native_bridge_library_path_ = options->native_bridge_library_path_;
+  if (!native_bridge_library_path_.empty()) {
+    android::SetupNativeBridge(native_bridge_library_path_.c_str(), &native_bridge_art_callbacks_);
+    VLOG(startup) << "Runtime::Setup native bridge library: " << native_bridge_library_path_;
+  }
 
   VLOG(startup) << "Runtime::Init exiting";
   return true;
diff --git a/runtime/runtime.h b/runtime/runtime.h
index a85c2e4..9c8a24c 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -31,6 +31,7 @@
 #include "instrumentation.h"
 #include "instruction_set.h"
 #include "jobject_comparator.h"
+#include "nativebridge/native_bridge.h"
 #include "object_callbacks.h"
 #include "offsets.h"
 #include "profiler_options.h"
@@ -611,6 +612,25 @@
   bool implicit_so_checks_;         // StackOverflow checks are implicit.
   bool implicit_suspend_checks_;    // Thread suspension checks are implicit.
 
+  // The path to the native bridge library. If this is not empty the native bridge will be
+  // initialized and loaded from the pointed path.
+  //
+  // The native bridge allows running native code compiled for a foreign ISA. The way it works is,
+  // if standard dlopen fails to load native library associated with native activity, it calls to
+  // the native bridge to load it and then gets the trampoline for the entry to native activity.
+  std::string native_bridge_library_path_;
+
+  // Native bridge library runtime callbacks. They represent the runtime interface to native bridge.
+  //
+  // The interface is expected to expose the following methods:
+  // getMethodShorty(): in the case of native method calling JNI native function CallXXXXMethodY(),
+  //   native bridge calls back to VM for the shorty of the method so that it can prepare based on
+  //   host calling convention.
+  // getNativeMethodCount() and getNativeMethods(): in case of JNI function UnregisterNatives(),
+  //   native bridge can call back to get all native methods of specified class so that all
+  //   corresponding trampolines can be destroyed.
+  android::NativeBridgeRuntimeCallbacks native_bridge_art_callbacks_;
+
   DISALLOW_COPY_AND_ASSIGN(Runtime);
 };
 
diff --git a/test/115-native-bridge/nativebridge.cc b/test/115-native-bridge/nativebridge.cc
index 268f0be..3acc643 100644
--- a/test/115-native-bridge/nativebridge.cc
+++ b/test/115-native-bridge/nativebridge.cc
@@ -22,27 +22,9 @@
 
 #include "jni.h"
 #include "stdio.h"
-#include "string.h"
 #include "unistd.h"
 
-#include "native_bridge.h"
-
-
-// Native bridge interfaces...
-
-struct NativeBridgeArtCallbacks {
-  const char* (*getMethodShorty)(JNIEnv* env, jmethodID mid);
-  uint32_t (*getNativeMethodCount)(JNIEnv* env, jclass clazz);
-  uint32_t (*getNativeMethods)(JNIEnv* env, jclass clazz, JNINativeMethod* methods,
-                               uint32_t method_count);
-};
-
-struct NativeBridgeCallbacks {
-  bool (*initialize)(NativeBridgeArtCallbacks* art_cbs);
-  void* (*loadLibrary)(const char* libpath, int flag);
-  void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len);
-  bool (*isSupported)(const char* libpath);
-};
+#include "nativebridge/native_bridge.h"
 
 struct NativeBridgeMethod {
   const char* name;
@@ -53,7 +35,7 @@
 };
 
 static NativeBridgeMethod* find_native_bridge_method(const char *name);
-static NativeBridgeArtCallbacks* gNativeBridgeArtCallbacks;
+static const android::NativeBridgeRuntimeCallbacks* gNativeBridgeArtCallbacks;
 
 static jint trampoline_JNI_OnLoad(JavaVM* vm, void* reserved) {
   JNIEnv* env = nullptr;
@@ -225,7 +207,7 @@
 }
 
 // NativeBridgeCallbacks implementations
-extern "C" bool native_bridge_initialize(NativeBridgeArtCallbacks* art_cbs) {
+extern "C" bool native_bridge_initialize(const android::NativeBridgeRuntimeCallbacks* art_cbs) {
   if (art_cbs != nullptr) {
     gNativeBridgeArtCallbacks = art_cbs;
     printf("Native bridge initialized.\n");
@@ -281,7 +263,9 @@
   return strcmp(libpath, "libjavacore.so") != 0;
 }
 
-NativeBridgeCallbacks NativeBridgeItf {
+// "NativeBridgeItf" is effectively an API (it is the name of the symbol that will be loaded
+// by the native bridge library).
+android::NativeBridgeCallbacks NativeBridgeItf {
   .initialize = &native_bridge_initialize,
   .loadLibrary = &native_bridge_loadLibrary,
   .getTrampoline = &native_bridge_getTrampoline,