/*
 * 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 "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 */
