/*
 * Copyright (C) 2012 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.
 */

#define LOG_TAG "BluetoothHeadsetServiceJni"

#define LOG_NDEBUG 0

#include "android_runtime/AndroidRuntime.h"
#include "com_android_bluetooth.h"
#include "hardware/bluetooth_headset_callbacks.h"
#include "hardware/bluetooth_headset_interface.h"
#include "hardware/bt_hf.h"
#include "utils/Log.h"

#include <mutex>
#include <shared_mutex>

namespace android {

static jmethodID method_onConnectionStateChanged;
static jmethodID method_onAudioStateChanged;
static jmethodID method_onVrStateChanged;
static jmethodID method_onAnswerCall;
static jmethodID method_onHangupCall;
static jmethodID method_onVolumeChanged;
static jmethodID method_onDialCall;
static jmethodID method_onSendDtmf;
static jmethodID method_onNoiseReductionEnable;
static jmethodID method_onWBS;
static jmethodID method_onAtChld;
static jmethodID method_onAtCnum;
static jmethodID method_onAtCind;
static jmethodID method_onAtCops;
static jmethodID method_onAtClcc;
static jmethodID method_onUnknownAt;
static jmethodID method_onKeyPressed;
static jmethodID method_onAtBind;
static jmethodID method_onAtBiev;
static jmethodID method_onAtBia;

static bluetooth::headset::Interface* sBluetoothHfpInterface = nullptr;
static std::shared_timed_mutex interface_mutex;

static jobject mCallbacksObj = nullptr;
static std::shared_timed_mutex callbacks_mutex;

static jbyteArray marshall_bda(RawAddress* bd_addr) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return nullptr;

  jbyteArray addr = sCallbackEnv->NewByteArray(sizeof(RawAddress));
  if (!addr) {
    ALOGE("Fail to new jbyteArray bd addr");
    return nullptr;
  }
  sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(RawAddress),
                                   (jbyte*)bd_addr);
  return addr;
}

class JniHeadsetCallbacks : bluetooth::headset::Callbacks {
 public:
  static bluetooth::headset::Callbacks* GetInstance() {
    static bluetooth::headset::Callbacks* instance = new JniHeadsetCallbacks();
    return instance;
  }

  void ConnectionStateCallback(
      bluetooth::headset::bthf_connection_state_t state,
      RawAddress* bd_addr) override {
    ALOGI("%s %d for %s", __func__, state, bd_addr->ToString().c_str());

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) return;

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged,
                                 (jint)state, addr.get());
  }

  void AudioStateCallback(bluetooth::headset::bthf_audio_state_t state,
                          RawAddress* bd_addr) override {
    ALOGI("%s, %d for %s", __func__, state, bd_addr->ToString().c_str());

    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) return;

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged,
                                 (jint)state, addr.get());
  }

  void VoiceRecognitionCallback(bluetooth::headset::bthf_vr_state_t state,
                                RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVrStateChanged,
                                 (jint)state, addr.get());
  }

  void AnswerCallCallback(RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAnswerCall,
                                 addr.get());
  }

  void HangupCallCallback(RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onHangupCall,
                                 addr.get());
  }

  void VolumeControlCallback(bluetooth::headset::bthf_volume_type_t type,
                             int volume, RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVolumeChanged,
                                 (jint)type, (jint)volume, addr.get());
  }

  void DialCallCallback(char* number, RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    char null_str[] = "";
    if (!sCallbackEnv.isValidUtf(number)) {
      android_errorWriteLog(0x534e4554, "109838537");
      ALOGE("%s: number is not a valid UTF string.", __func__);
      number = null_str;
    }

    ScopedLocalRef<jstring> js_number(sCallbackEnv.get(),
                                      sCallbackEnv->NewStringUTF(number));
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDialCall,
                                 js_number.get(), addr.get());
  }

  void DtmfCmdCallback(char dtmf, RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    // TBD dtmf has changed from int to char
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSendDtmf, dtmf,
                                 addr.get());
  }

  void NoiseReductionCallback(bluetooth::headset::bthf_nrec_t nrec,
                              RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNoiseReductionEnable,
                                 nrec == bluetooth::headset::BTHF_NREC_START,
                                 addr.get());
  }

  void WbsCallback(bluetooth::headset::bthf_wbs_config_t wbs_config,
                   RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (addr.get() == nullptr) return;

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWBS, wbs_config,
                                 addr.get());
  }

  void AtChldCallback(bluetooth::headset::bthf_chld_type_t chld,
                      RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(
        sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
                                     (jbyte*)bd_addr);
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtChld, chld,
                                 addr.get());
  }

  void AtCnumCallback(RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCnum, addr.get());
  }

  void AtCindCallback(RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCind, addr.get());
  }

  void AtCopsCallback(RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtCops, addr.get());
  }

  void AtClccCallback(RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtClcc, addr.get());
  }

  void UnknownAtCallback(char* at_string, RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    char null_str[] = "";
    if (!sCallbackEnv.isValidUtf(at_string)) {
      android_errorWriteLog(0x534e4554, "109838537");
      ALOGE("%s: at_string is not a valid UTF string.", __func__);
      at_string = null_str;
    }

    ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(),
                                         sCallbackEnv->NewStringUTF(at_string));
    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onUnknownAt,
                                 js_at_string.get(), addr.get());
  }

  void KeyPressedCallback(RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (!addr.get()) {
      ALOGE("Fail to new jbyteArray bd addr for audio state");
      return;
    }

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onKeyPressed,
                                 addr.get());
  }

  void AtBindCallback(char* at_string, RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (addr.get() == nullptr) return;

    char null_str[] = "";
    if (!sCallbackEnv.isValidUtf(at_string)) {
      android_errorWriteLog(0x534e4554, "109838537");
      ALOGE("%s: at_string is not a valid UTF string.", __func__);
      at_string = null_str;
    }

    ScopedLocalRef<jstring> js_at_string(sCallbackEnv.get(),
                                         sCallbackEnv->NewStringUTF(at_string));

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBind,
                                 js_at_string.get(), addr.get());
  }

  void AtBievCallback(bluetooth::headset::bthf_hf_ind_type_t ind_id,
                      int ind_value, RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (addr.get() == nullptr) return;

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBiev, ind_id,
                                 (jint)ind_value, addr.get());
  }

  void AtBiaCallback(bool service, bool roam, bool signal, bool battery,
                     RawAddress* bd_addr) override {
    std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex);
    CallbackEnv sCallbackEnv(__func__);
    if (!sCallbackEnv.valid() || !mCallbacksObj) return;

    ScopedLocalRef<jbyteArray> addr(sCallbackEnv.get(), marshall_bda(bd_addr));
    if (addr.get() == nullptr) return;

    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAtBia, service, roam,
                                 signal, battery, addr.get());
  }
};

static void classInitNative(JNIEnv* env, jclass clazz) {
  method_onConnectionStateChanged =
      env->GetMethodID(clazz, "onConnectionStateChanged", "(I[B)V");
  method_onAudioStateChanged =
      env->GetMethodID(clazz, "onAudioStateChanged", "(I[B)V");
  method_onVrStateChanged =
      env->GetMethodID(clazz, "onVrStateChanged", "(I[B)V");
  method_onAnswerCall = env->GetMethodID(clazz, "onAnswerCall", "([B)V");
  method_onHangupCall = env->GetMethodID(clazz, "onHangupCall", "([B)V");
  method_onVolumeChanged =
      env->GetMethodID(clazz, "onVolumeChanged", "(II[B)V");
  method_onDialCall =
      env->GetMethodID(clazz, "onDialCall", "(Ljava/lang/String;[B)V");
  method_onSendDtmf = env->GetMethodID(clazz, "onSendDtmf", "(I[B)V");
  method_onNoiseReductionEnable =
      env->GetMethodID(clazz, "onNoiseReductionEnable", "(Z[B)V");
  method_onWBS = env->GetMethodID(clazz, "onWBS", "(I[B)V");
  method_onAtChld = env->GetMethodID(clazz, "onAtChld", "(I[B)V");
  method_onAtCnum = env->GetMethodID(clazz, "onAtCnum", "([B)V");
  method_onAtCind = env->GetMethodID(clazz, "onAtCind", "([B)V");
  method_onAtCops = env->GetMethodID(clazz, "onAtCops", "([B)V");
  method_onAtClcc = env->GetMethodID(clazz, "onAtClcc", "([B)V");
  method_onUnknownAt =
      env->GetMethodID(clazz, "onUnknownAt", "(Ljava/lang/String;[B)V");
  method_onKeyPressed = env->GetMethodID(clazz, "onKeyPressed", "([B)V");
  method_onAtBind =
      env->GetMethodID(clazz, "onATBind", "(Ljava/lang/String;[B)V");
  method_onAtBiev = env->GetMethodID(clazz, "onATBiev", "(II[B)V");
  method_onAtBia = env->GetMethodID(clazz, "onAtBia", "(ZZZZ[B)V");

  ALOGI("%s: succeeds", __func__);
}

static void initializeNative(JNIEnv* env, jobject object, jint max_hf_clients,
                             jboolean inband_ringing_enabled) {
  std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
  std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);

  const bt_interface_t* btInf = getBluetoothInterface();
  if (!btInf) {
    ALOGE("%s: Bluetooth module is not loaded", __func__);
    jniThrowIOException(env, EINVAL);
    return;
  }

  if (sBluetoothHfpInterface) {
    ALOGI("%s: Cleaning up Bluetooth Handsfree Interface before initializing",
          __func__);
    sBluetoothHfpInterface->Cleanup();
    sBluetoothHfpInterface = nullptr;
  }

  if (mCallbacksObj) {
    ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__);
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = nullptr;
  }

  sBluetoothHfpInterface =
      (bluetooth::headset::Interface*)btInf->get_profile_interface(
          BT_PROFILE_HANDSFREE_ID);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: Failed to get Bluetooth Handsfree Interface", __func__);
    jniThrowIOException(env, EINVAL);
    return;
  }
  bt_status_t status =
      sBluetoothHfpInterface->Init(JniHeadsetCallbacks::GetInstance(),
                                   max_hf_clients, inband_ringing_enabled);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("%s: Failed to initialize Bluetooth Handsfree Interface, status: %d",
          __func__, status);
    sBluetoothHfpInterface = nullptr;
    return;
  }

  mCallbacksObj = env->NewGlobalRef(object);
}

static void cleanupNative(JNIEnv* env, jobject object) {
  std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex);
  std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex);

  const bt_interface_t* btInf = getBluetoothInterface();
  if (!btInf) {
    ALOGW("%s: Bluetooth module is not loaded", __func__);
    return;
  }

  if (sBluetoothHfpInterface) {
    ALOGI("%s: Cleaning up Bluetooth Handsfree Interface", __func__);
    sBluetoothHfpInterface->Cleanup();
    sBluetoothHfpInterface = nullptr;
  }

  if (mCallbacksObj) {
    ALOGI("%s: Cleaning up Bluetooth Handsfree callback object", __func__);
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = nullptr;
  }
}

static jboolean connectHfpNative(JNIEnv* env, jobject object,
                                 jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
  bt_status_t status = sBluetoothHfpInterface->Connect((RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed HF connection, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean disconnectHfpNative(JNIEnv* env, jobject object,
                                    jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
  bt_status_t status = sBluetoothHfpInterface->Disconnect((RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed HF disconnection, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean connectAudioNative(JNIEnv* env, jobject object,
                                   jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
  bt_status_t status = sBluetoothHfpInterface->ConnectAudio((RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed HF audio connection, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean disconnectAudioNative(JNIEnv* env, jobject object,
                                      jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  ALOGI("%s: device %s", __func__, ((RawAddress*)addr)->ToString().c_str());
  bt_status_t status =
      sBluetoothHfpInterface->DisconnectAudio((RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed HF audio disconnection, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean startVoiceRecognitionNative(JNIEnv* env, jobject object,
                                            jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status =
      sBluetoothHfpInterface->StartVoiceRecognition((RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed to start voice recognition, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean stopVoiceRecognitionNative(JNIEnv* env, jobject object,
                                           jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status =
      sBluetoothHfpInterface->StopVoiceRecognition((RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed to stop voice recognition, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume_type,
                                jint volume, jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status = sBluetoothHfpInterface->VolumeControl(
      (bluetooth::headset::bthf_volume_type_t)volume_type, volume,
      (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("FAILED to control volume, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean notifyDeviceStatusNative(JNIEnv* env, jobject object,
                                         jint network_state, jint service_type,
                                         jint signal, jint battery_charge,
                                         jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status = sBluetoothHfpInterface->DeviceStatusNotification(
      (bluetooth::headset::bthf_network_state_t)network_state,
      (bluetooth::headset::bthf_service_type_t)service_type, signal,
      battery_charge, (RawAddress*)addr);
  env->ReleaseByteArrayElements(address, addr, 0);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("FAILED to notify device status, status: %d", status);
  }
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean copsResponseNative(JNIEnv* env, jobject object,
                                   jstring operator_str, jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  const char* operator_name = env->GetStringUTFChars(operator_str, nullptr);
  bt_status_t status =
      sBluetoothHfpInterface->CopsResponse(operator_name, (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed sending cops response, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  env->ReleaseStringUTFChars(operator_str, operator_name);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean cindResponseNative(JNIEnv* env, jobject object, jint service,
                                   jint num_active, jint num_held,
                                   jint call_state, jint signal, jint roam,
                                   jint battery_charge, jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status = sBluetoothHfpInterface->CindResponse(
      service, num_active, num_held,
      (bluetooth::headset::bthf_call_state_t)call_state, signal, roam,
      battery_charge, (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("%s: failed, status: %d", __func__, status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean atResponseStringNative(JNIEnv* env, jobject object,
                                       jstring response_str,
                                       jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  const char* response = env->GetStringUTFChars(response_str, nullptr);
  bt_status_t status =
      sBluetoothHfpInterface->FormattedAtResponse(response, (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed formatted AT response, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  env->ReleaseStringUTFChars(response_str, response);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean atResponseCodeNative(JNIEnv* env, jobject object,
                                     jint response_code, jint cmee_code,
                                     jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status = sBluetoothHfpInterface->AtResponse(
      (bluetooth::headset::bthf_at_response_t)response_code, cmee_code,
      (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed AT response, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean clccResponseNative(JNIEnv* env, jobject object, jint index,
                                   jint dir, jint callStatus, jint mode,
                                   jboolean mpty, jstring number_str, jint type,
                                   jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  const char* number = nullptr;
  if (number_str) {
    number = env->GetStringUTFChars(number_str, nullptr);
  }
  bt_status_t status = sBluetoothHfpInterface->ClccResponse(
      index, (bluetooth::headset::bthf_call_direction_t)dir,
      (bluetooth::headset::bthf_call_state_t)callStatus,
      (bluetooth::headset::bthf_call_mode_t)mode,
      mpty ? bluetooth::headset::BTHF_CALL_MPTY_TYPE_MULTI
           : bluetooth::headset::BTHF_CALL_MPTY_TYPE_SINGLE,
      number, (bluetooth::headset::bthf_call_addrtype_t)type,
      (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed sending CLCC response, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  if (number) {
    env->ReleaseStringUTFChars(number_str, number);
  }
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean phoneStateChangeNative(JNIEnv* env, jobject object,
                                       jint num_active, jint num_held,
                                       jint call_state, jstring number_str,
                                       jint type, jstring name_str,
                                       jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, nullptr);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  const char* number = env->GetStringUTFChars(number_str, nullptr);
  const char* name = nullptr;
  if (name_str != nullptr) {
    name = env->GetStringUTFChars(name_str, nullptr);
  }
  bt_status_t status = sBluetoothHfpInterface->PhoneStateChange(
      num_active, num_held, (bluetooth::headset::bthf_call_state_t)call_state,
      number, (bluetooth::headset::bthf_call_addrtype_t)type, name,
      (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed report phone state change, status: %d", status);
  }
  env->ReleaseStringUTFChars(number_str, number);
  if (name != nullptr) {
    env->ReleaseStringUTFChars(name_str, name);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setScoAllowedNative(JNIEnv* env, jobject object,
                                    jboolean value) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  bt_status_t status = sBluetoothHfpInterface->SetScoAllowed(value == JNI_TRUE);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed HF set sco allowed, status: %d", status);
  }
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean sendBsirNative(JNIEnv* env, jobject object, jboolean value,
                               jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status =
      sBluetoothHfpInterface->SendBsir(value == JNI_TRUE, (RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed sending BSIR, value=%d, status=%d", value, status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setActiveDeviceNative(JNIEnv* env, jobject object,
                                      jbyteArray address) {
  std::shared_lock<std::shared_timed_mutex> lock(interface_mutex);
  if (!sBluetoothHfpInterface) {
    ALOGW("%s: sBluetoothHfpInterface is null", __func__);
    return JNI_FALSE;
  }
  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    ALOGE("%s: failed to get device address", __func__);
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }
  bt_status_t status =
      sBluetoothHfpInterface->SetActiveDevice((RawAddress*)addr);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed to set active device, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void*)classInitNative},
    {"initializeNative", "(IZ)V", (void*)initializeNative},
    {"cleanupNative", "()V", (void*)cleanupNative},
    {"connectHfpNative", "([B)Z", (void*)connectHfpNative},
    {"disconnectHfpNative", "([B)Z", (void*)disconnectHfpNative},
    {"connectAudioNative", "([B)Z", (void*)connectAudioNative},
    {"disconnectAudioNative", "([B)Z", (void*)disconnectAudioNative},
    {"startVoiceRecognitionNative", "([B)Z",
     (void*)startVoiceRecognitionNative},
    {"stopVoiceRecognitionNative", "([B)Z", (void*)stopVoiceRecognitionNative},
    {"setVolumeNative", "(II[B)Z", (void*)setVolumeNative},
    {"notifyDeviceStatusNative", "(IIII[B)Z", (void*)notifyDeviceStatusNative},
    {"copsResponseNative", "(Ljava/lang/String;[B)Z",
     (void*)copsResponseNative},
    {"cindResponseNative", "(IIIIIII[B)Z", (void*)cindResponseNative},
    {"atResponseStringNative", "(Ljava/lang/String;[B)Z",
     (void*)atResponseStringNative},
    {"atResponseCodeNative", "(II[B)Z", (void*)atResponseCodeNative},
    {"clccResponseNative", "(IIIIZLjava/lang/String;I[B)Z",
     (void*)clccResponseNative},
    {"phoneStateChangeNative", "(IIILjava/lang/String;ILjava/lang/String;[B)Z",
     (void*)phoneStateChangeNative},
    {"setScoAllowedNative", "(Z)Z", (void*)setScoAllowedNative},
    {"sendBsirNative", "(Z[B)Z", (void*)sendBsirNative},
    {"setActiveDeviceNative", "([B)Z", (void*)setActiveDeviceNative},
};

int register_com_android_bluetooth_hfp(JNIEnv* env) {
  return jniRegisterNativeMethods(
      env, "com/android/bluetooth/hfp/HeadsetNativeInterface", sMethods,
      NELEM(sMethods));
}

} /* namespace android */
