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

Commit 602f4c1c 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 71d3236f
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
namespace android {

JNIEnv* getCallbackEnv();
bool isCallbackThread();

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

    bool valid() const {
      JNIEnv *env = AndroidRuntime::getJNIEnv();
      if (!mCallbackEnv || (mCallbackEnv != env)) {
          ALOGE("%s: Callback env fail: env: %p, callback: %p", mName, env, mCallbackEnv);
      if (!mCallbackEnv || !isCallbackThread()) {
        ALOGE("%s: Callback env fail", mName);
        return false;
      }
      return true;
+21 −9
Original line number Diff line number Diff line
@@ -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 struct {

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 @@ const bt_interface_t* getBluetoothInterface() { return sBluetoothInterface; }

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 ssp_request_callback(RawAddress* bd_addr, bt_bdname_t* bdname,
}

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 @@ static void callback_thread_event(bt_cb_thread_evt event) {
    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 @@ static void* sAlarmCallbackData;

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 @@ class JNIThreadAttacher {

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 bool set_wake_alarm_callout(uint64_t delay_millis, bool should_wake,
}

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 acquire_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();

  if (env == nullptr) {
@@ -678,6 +686,10 @@ static void classInitNative(JNIEnv* env, jclass clazz) {
  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");
  }