Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44ea7018 authored by Zach Johnson's avatar Zach Johnson
Browse files

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
parent 0a870493
Loading
Loading
Loading
Loading
+4 −4
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@
namespace android {
namespace android {


JNIEnv* getCallbackEnv();
JNIEnv* getCallbackEnv();
bool isCallbackThread();


class CallbackEnv {
class CallbackEnv {
public:
public:
@@ -46,9 +47,8 @@ public:
    }
    }


    bool valid() const {
    bool valid() const {
      JNIEnv *env = AndroidRuntime::getJNIEnv();
      if (!mCallbackEnv || !isCallbackThread()) {
      if (!mCallbackEnv || (mCallbackEnv != env)) {
        ALOGE("%s: Callback env fail", mName);
          ALOGE("%s: Callback env fail: env: %p, callback: %p", mName, env, mCallbackEnv);
        return false;
        return false;
      }
      }
      return true;
      return true;
+21 −9
Original line number Original line Diff line number Diff line
@@ -15,8 +15,6 @@
 */
 */


#define LOG_TAG "BluetoothServiceJni"
#define LOG_TAG "BluetoothServiceJni"
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
#include "bluetooth_socket_manager.h"
#include "bluetooth_socket_manager.h"
#include "com_android_bluetooth.h"
#include "com_android_bluetooth.h"
#include "hardware/bt_sock.h"
#include "hardware/bt_sock.h"
@@ -40,6 +38,8 @@
#include <hardware/bluetooth.h>
#include <hardware/bluetooth.h>
#include <mutex>
#include <mutex>


#include <pthread.h>

using android::bluetooth::BluetoothSocketManagerBinderServer;
using android::bluetooth::BluetoothSocketManagerBinderServer;


namespace android {
namespace android {
@@ -70,7 +70,10 @@ static struct {


static const bt_interface_t* sBluetoothInterface = NULL;
static const bt_interface_t* sBluetoothInterface = NULL;
static const btsock_interface_t* sBluetoothSocketInterface = NULL;
static const btsock_interface_t* sBluetoothSocketInterface = NULL;
static JavaVM* vm = NULL;
static JNIEnv* callbackEnv = NULL;
static JNIEnv* callbackEnv = NULL;
static pthread_t sCallbackThread;
static bool sHaveCallbackThread;


static jobject sJniAdapterServiceObj;
static jobject sJniAdapterServiceObj;
static jobject sJniCallbacksObj;
static jobject sJniCallbacksObj;
@@ -85,6 +88,10 @@ const bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }


JNIEnv* getCallbackEnv() { return callbackEnv; }
JNIEnv* getCallbackEnv() { return callbackEnv; }


bool isCallbackThread() {
  return sHaveCallbackThread && pthread_equal(sCallbackThread, pthread_self());
}

static void adapter_state_change_callback(bt_state_t status) {
static void adapter_state_change_callback(bt_state_t status) {
  CallbackEnv sCallbackEnv(__func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!sCallbackEnv.valid()) return;
@@ -389,7 +396,6 @@ static void ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
}
}


static void callback_thread_event(bt_cb_thread_evt event) {
static void callback_thread_event(bt_cb_thread_evt event) {
  JavaVM* vm = AndroidRuntime::getJavaVM();
  if (event == ASSOCIATE_JVM) {
  if (event == ASSOCIATE_JVM) {
    JavaVMAttachArgs args;
    JavaVMAttachArgs args;
    char name[] = "BT Service Callback Thread";
    char name[] = "BT Service Callback Thread";
@@ -397,13 +403,16 @@ static void callback_thread_event(bt_cb_thread_evt event) {
    args.name = name;
    args.name = name;
    args.group = NULL;
    args.group = NULL;
    vm->AttachCurrentThread(&callbackEnv, &args);
    vm->AttachCurrentThread(&callbackEnv, &args);
    sHaveCallbackThread = true;
    sCallbackThread = pthread_self();
    ALOGV("Callback thread attached: %p", callbackEnv);
    ALOGV("Callback thread attached: %p", callbackEnv);
  } else if (event == DISASSOCIATE_JVM) {
  } else if (event == DISASSOCIATE_JVM) {
    if (callbackEnv != AndroidRuntime::getJNIEnv()) {
    if (!isCallbackThread()) {
      ALOGE("Callback: '%s' is not called on the correct thread", __func__);
      ALOGE("Callback: '%s' is not called on the correct thread", __func__);
      return;
      return;
    }
    }
    vm->DetachCurrentThread();
    vm->DetachCurrentThread();
    sHaveCallbackThread = false;
  }
  }
}
}


@@ -463,8 +472,7 @@ static void* sAlarmCallbackData;


class JNIThreadAttacher {
class JNIThreadAttacher {
 public:
 public:
  JNIThreadAttacher() : vm_(nullptr), env_(nullptr) {
  JNIThreadAttacher(JavaVM* vm) : vm_(vm), env_(nullptr) {
    vm_ = AndroidRuntime::getJavaVM();
    status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);
    status_ = vm_->GetEnv((void**)&env_, JNI_VERSION_1_6);


    if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
    if (status_ != JNI_OK && status_ != JNI_EDETACHED) {
@@ -510,7 +518,7 @@ class JNIThreadAttacher {


static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
                                   alarm_cb cb, void* data) {
                                   alarm_cb cb, void* data) {
  JNIThreadAttacher attacher;
  JNIThreadAttacher attacher(vm);
  JNIEnv* env = attacher.getEnv();
  JNIEnv* env = attacher.getEnv();


  if (env == nullptr) {
  if (env == nullptr) {
@@ -534,7 +542,7 @@ static bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
}
}


static int acquire_wake_lock_callout(const char* lock_name) {
static int acquire_wake_lock_callout(const char* lock_name) {
  JNIThreadAttacher attacher;
  JNIThreadAttacher attacher(vm);
  JNIEnv* env = attacher.getEnv();
  JNIEnv* env = attacher.getEnv();


  if (env == nullptr) {
  if (env == nullptr) {
@@ -559,7 +567,7 @@ static int acquire_wake_lock_callout(const char* lock_name) {
}
}


static int release_wake_lock_callout(const char* lock_name) {
static int release_wake_lock_callout(const char* lock_name) {
  JNIThreadAttacher attacher;
  JNIThreadAttacher attacher(vm);
  JNIEnv* env = attacher.getEnv();
  JNIEnv* env = attacher.getEnv();


  if (env == nullptr) {
  if (env == nullptr) {
@@ -678,6 +686,10 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
  method_energyInfo = env->GetMethodID(
  method_energyInfo = env->GetMethodID(
      clazz, "energyInfoCallback", "(IIJJJJ[Landroid/bluetooth/UidTraffic;)V");
      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)) {
  if (hal_util_load_bt_library((bt_interface_t const**)&sBluetoothInterface)) {
    ALOGE("No Bluetooth Library found");
    ALOGE("No Bluetooth Library found");
  }
  }