Remove need to call into android_runtime

Save the VM ahead of time, and use that instead
of fetching from AndroidRuntime.

Check the underlying pthreads to verify we're on
the correct thread to make callbacks.

This will ensure we can use the ndk version of
libnativehelper instead.

Bug: 143971120
Test: compile, boot, and check things that invoke callbacks (like discovery) still work
Change-Id: I37b249e40fa7da50b32ecf5dea9974b22a04fd47
diff --git a/jni/com_android_bluetooth.h b/jni/com_android_bluetooth.h
index 2076779..13ba8d4 100644
--- a/jni/com_android_bluetooth.h
+++ b/jni/com_android_bluetooth.h
@@ -30,6 +30,7 @@
 namespace android {
 
 JNIEnv* getCallbackEnv();
+bool isCallbackThread();
 
 class CallbackEnv {
 public:
@@ -46,10 +47,9 @@
     }
 
     bool valid() const {
-      JNIEnv *env = AndroidRuntime::getJNIEnv();
-      if (!mCallbackEnv || (mCallbackEnv != env)) {
-          ALOGE("%s: Callback env fail: env: %p, callback: %p", mName, env, mCallbackEnv);
-          return false;
+      if (!mCallbackEnv || !isCallbackThread()) {
+        ALOGE("%s: Callback env fail", mName);
+        return false;
       }
       return true;
     }
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp
index 0ac85f4..775fb37 100644
--- a/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -15,8 +15,6 @@
  */
 
 #define LOG_TAG "BluetoothServiceJni"
-#include "android_runtime/AndroidRuntime.h"
-#include "android_runtime/Log.h"
 #include "bluetooth_socket_manager.h"
 #include "com_android_bluetooth.h"
 #include "hardware/bt_sock.h"
@@ -40,6 +38,8 @@
 #include <hardware/bluetooth.h>
 #include <mutex>
 
+#include <pthread.h>
+
 using android::bluetooth::BluetoothSocketManagerBinderServer;
 
 namespace android {
@@ -70,7 +70,10 @@
 
 static const bt_interface_t* sBluetoothInterface = NULL;
 static const btsock_interface_t* sBluetoothSocketInterface = NULL;
+static JavaVM* vm = NULL;
 static JNIEnv* callbackEnv = NULL;
+static pthread_t sCallbackThread;
+static bool sHaveCallbackThread;
 
 static jobject sJniAdapterServiceObj;
 static jobject sJniCallbacksObj;
@@ -85,6 +88,10 @@
 
 JNIEnv* getCallbackEnv() { return callbackEnv; }
 
+bool isCallbackThread() {
+  return sHaveCallbackThread && pthread_equal(sCallbackThread, pthread_self());
+}
+
 static void adapter_state_change_callback(bt_state_t status) {
   CallbackEnv sCallbackEnv(__func__);
   if (!sCallbackEnv.valid()) return;
@@ -389,7 +396,6 @@
 }
 
 static void callback_thread_event(bt_cb_thread_evt event) {
-  JavaVM* vm = AndroidRuntime::getJavaVM();
   if (event == ASSOCIATE_JVM) {
     JavaVMAttachArgs args;
     char name[] = "BT Service Callback Thread";
@@ -397,13 +403,16 @@
     args.name = name;
     args.group = NULL;
     vm->AttachCurrentThread(&callbackEnv, &args);
+    sHaveCallbackThread = true;
+    sCallbackThread = pthread_self();
     ALOGV("Callback thread attached: %p", callbackEnv);
   } else if (event == DISASSOCIATE_JVM) {
-    if (callbackEnv != AndroidRuntime::getJNIEnv()) {
+    if (!isCallbackThread()) {
       ALOGE("Callback: '%s' is not called on the correct thread", __func__);
       return;
     }
     vm->DetachCurrentThread();
+    sHaveCallbackThread = false;
   }
 }
 
@@ -463,8 +472,7 @@
 
 class JNIThreadAttacher {
  public:
-  JNIThreadAttacher() : vm_(nullptr), env_(nullptr) {
-    vm_ = AndroidRuntime::getJavaVM();
+  JNIThreadAttacher(JavaVM* vm) : vm_(vm), env_(nullptr) {
     status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);
 
     if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
@@ -510,7 +518,7 @@
 
 static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
                                    alarm_cb cb, void* data) {
-  JNIThreadAttacher attacher;
+  JNIThreadAttacher attacher(vm);
   JNIEnv* env = attacher.getEnv();
 
   if (env == nullptr) {
@@ -534,7 +542,7 @@
 }
 
 static int acquire_wake_lock_callout(const char* lock_name) {
-  JNIThreadAttacher attacher;
+  JNIThreadAttacher attacher(vm);
   JNIEnv* env = attacher.getEnv();
 
   if (env == nullptr) {
@@ -559,7 +567,7 @@
 }
 
 static int release_wake_lock_callout(const char* lock_name) {
-  JNIThreadAttacher attacher;
+  JNIThreadAttacher attacher(vm);
   JNIEnv* env = attacher.getEnv();
 
   if (env == nullptr) {
@@ -678,6 +686,10 @@
   method_energyInfo = env->GetMethodID(
       clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
 
+  if (env->GetJavaVM(&vm) != JNI_OK) {
+    ALOGE("Could not get JavaVM");
+  }
+
   if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {
     ALOGE("No Bluetooth Library found");
   }