/*
 * Copyright (C) 2016 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 "BluetoothAvrcpServiceJni"

#define LOG_NDEBUG 0

#include "android_runtime/AndroidRuntime.h"
#include "com_android_bluetooth.h"
#include "hardware/bt_rc.h"
#include "utils/Log.h"

#include <string.h>

namespace android {
static jmethodID method_getRcFeatures;
static jmethodID method_getPlayStatus;
static jmethodID method_getElementAttr;
static jmethodID method_registerNotification;
static jmethodID method_volumeChangeCallback;
static jmethodID method_handlePassthroughCmd;
static jmethodID method_getFolderItemsCallback;
static jmethodID method_setAddressedPlayerCallback;

static jmethodID method_setBrowsedPlayerCallback;
static jmethodID method_changePathCallback;
static jmethodID method_searchCallback;
static jmethodID method_playItemCallback;
static jmethodID method_getItemAttrCallback;
static jmethodID method_addToPlayListCallback;
static jmethodID method_getTotalNumOfItemsCallback;

static const btrc_interface_t* sBluetoothAvrcpInterface = NULL;
static jobject mCallbacksObj = NULL;

/* Function declarations */
static bool copy_item_attributes(JNIEnv* env, jobject object,
                                 btrc_folder_items_t* pitem,
                                 jint* p_attributesIds,
                                 jobjectArray attributesArray, int item_idx,
                                 int attribCopiedIndex);

static bool copy_jstring(uint8_t* str, int maxBytes, jstring jstr, JNIEnv* env);

static void cleanup_items(btrc_folder_items_t* p_items, int numItems);

static void btavrcp_remote_features_callback(bt_bdaddr_t* bd_addr,
                                             btrc_remote_features_t features) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
  if (!addr.get()) {
    ALOGE("Unable to allocate byte array for bd_addr");
    return;
  }

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr.get(),
                               (jint)features);
}

/** Callback for play status request */
static void btavrcp_get_play_status_callback(bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getPlayStatus, addr.get());
}

static void btavrcp_get_element_attr_callback(uint8_t num_attr,
                                              btrc_media_attr_t* p_attrs,
                                              bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  ScopedLocalRef<jintArray> attrs(
      sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_attr));
  if (!attrs.get()) {
    ALOGE("Fail to new jintArray for attrs");
    return;
  }

  sCallbackEnv->SetIntArrayRegion(attrs.get(), 0, num_attr, (jint*)p_attrs);

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getElementAttr, addr.get(),
                               (jbyte)num_attr, attrs.get());
}

static void btavrcp_register_notification_callback(btrc_event_id_t event_id,
                                                   uint32_t param,
                                                   bt_bdaddr_t* bd_addr) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_registerNotification,
                               addr.get(), (jint)event_id, (jint)param);
}

static void btavrcp_volume_change_callback(uint8_t volume, uint8_t ctype,
                                           bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);

  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_volumeChangeCallback,
                               addr.get(), (jint)volume, (jint)ctype);
}

static void btavrcp_passthrough_command_callback(int id, int pressed,
                                                 bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
  if (!addr.get()) {
    ALOGE("Fail to new jbyteArray bd addr for passthrough_command command");
    return;
  }
  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);

  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handlePassthroughCmd,
                               addr.get(), (jint)id, (jint)pressed);
}

static void btavrcp_set_addressed_player_callback(uint16_t player_id,
                                                  bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_setAddressedPlayerCallback,
                               addr.get(), (jint)player_id);
}

static void btavrcp_set_browsed_player_callback(uint16_t player_id,
                                                bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> addr(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
  if (!addr.get()) {
    ALOGE("Fail to new jbyteArray bd addr for set_browsed_player command");
    return;
  }
  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);

  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_setBrowsedPlayerCallback,
                               addr.get(), (jint)player_id);
}

static void btavrcp_get_folder_items_callback(
    uint8_t scope, uint32_t start_item, uint32_t end_item, uint8_t num_attr,
    uint32_t* p_attr_ids, bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  uint32_t* puiAttr = (uint32_t*)p_attr_ids;
  ScopedLocalRef<jintArray> attr_ids(sCallbackEnv.get(), NULL);
  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);

  /* check number of attributes requested by remote device */
  if ((num_attr != BTRC_NUM_ATTR_ALL) && (num_attr != BTRC_NUM_ATTR_NONE)) {
    /* allocate memory for attr_ids only if some attributes passed from below
     * layer */
    attr_ids.reset((jintArray)sCallbackEnv->NewIntArray(num_attr));
    if (!attr_ids.get()) {
      ALOGE("Fail to allocate new jintArray for attrs");
      return;
    }
    sCallbackEnv->SetIntArrayRegion(attr_ids.get(), 0, num_attr,
                                    (jint*)puiAttr);
  }

  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getFolderItemsCallback,
                               addr.get(), (jbyte)scope, (jint)start_item,
                               (jint)end_item, (jbyte)num_attr, attr_ids.get());
}

static void btavrcp_change_path_callback(uint8_t direction, uint8_t* folder_uid,
                                         bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> attrs(sCallbackEnv.get(),
                                   sCallbackEnv->NewByteArray(BTRC_UID_SIZE));
  if (!attrs.get()) {
    ALOGE("Fail to new jintArray for attrs");
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->SetByteArrayRegion(
      attrs.get(), 0, sizeof(uint8_t) * BTRC_UID_SIZE, (jbyte*)folder_uid);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_changePathCallback,
                               addr.get(), (jbyte)direction, attrs.get());
}

static void btavrcp_get_item_attr_callback(uint8_t scope, uint8_t* uid,
                                           uint16_t uid_counter,
                                           uint8_t num_attr,
                                           btrc_media_attr_t* p_attrs,
                                           bt_bdaddr_t* bd_addr) {
  ALOGI("%s", __func__);
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;

  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> attr_uid(
      sCallbackEnv.get(), sCallbackEnv->NewByteArray(BTRC_UID_SIZE));
  if (!attr_uid.get()) {
    ALOGE("Fail to new jintArray for attr_uid");
    return;
  }

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

  ScopedLocalRef<jintArray> attrs(
      sCallbackEnv.get(), (jintArray)sCallbackEnv->NewIntArray(num_attr));
  if (!attrs.get()) {
    ALOGE("Fail to new jintArray for attrs");
    return;
  }

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->SetIntArrayRegion(attrs.get(), 0, num_attr, (jint*)p_attrs);
  sCallbackEnv->SetByteArrayRegion(
      attr_uid.get(), 0, sizeof(uint8_t) * BTRC_UID_SIZE, (jbyte*)uid);

  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getItemAttrCallback,
                               addr.get(), (jbyte)scope, attr_uid.get(),
                               (jint)uid_counter, (jbyte)num_attr, attrs.get());
}

static void btavrcp_play_item_callback(uint8_t scope, uint16_t uid_counter,
                                       uint8_t* uid, bt_bdaddr_t* bd_addr) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> attrs(sCallbackEnv.get(),
                                   sCallbackEnv->NewByteArray(BTRC_UID_SIZE));
  if (!attrs.get()) {
    ALOGE("%s:Fail to new jByteArray attrs for play_item command", __func__);
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->SetByteArrayRegion(
      attrs.get(), 0, sizeof(uint8_t) * BTRC_UID_SIZE, (jbyte*)uid);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_playItemCallback,
                               addr.get(), (jbyte)scope, (jint)uid_counter,
                               attrs.get());
}

static void btavrcp_get_total_num_items_callback(uint8_t scope,
                                                 bt_bdaddr_t* bd_addr) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getTotalNumOfItemsCallback,
                               addr.get(), (jbyte)scope);
}

static void btavrcp_search_callback(uint16_t charset_id, uint16_t str_len,
                                    uint8_t* p_str, bt_bdaddr_t* bd_addr) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

  ScopedLocalRef<jbyteArray> attrs(sCallbackEnv.get(),
                                   sCallbackEnv->NewByteArray(str_len));
  if (!attrs.get()) {
    ALOGE("Fail to new jintArray for attrs");
    return;
  }

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

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->SetByteArrayRegion(attrs.get(), 0, str_len * sizeof(uint8_t),
                                   (jbyte*)p_str);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_searchCallback, addr.get(),
                               (jint)charset_id, attrs.get());
}

static void btavrcp_add_to_play_list_callback(uint8_t scope, uint8_t* uid,
                                              uint16_t uid_counter,
                                              bt_bdaddr_t* bd_addr) {
  CallbackEnv sCallbackEnv(__func__);
  if (!sCallbackEnv.valid()) return;
  if (!mCallbacksObj) {
    ALOGE("%s: mCallbacksObj is null", __func__);
    return;
  }

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

  ScopedLocalRef<jbyteArray> attrs(sCallbackEnv.get(),
                                   sCallbackEnv->NewByteArray(BTRC_UID_SIZE));
  if (!attrs.get()) {
    ALOGE("Fail to new jByteArray for attrs");
    return;
  }

  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
                                   (jbyte*)bd_addr);
  sCallbackEnv->SetByteArrayRegion(
      attrs.get(), 0, sizeof(uint8_t) * BTRC_UID_SIZE, (jbyte*)uid);
  sCallbackEnv->CallVoidMethod(mCallbacksObj, method_addToPlayListCallback,
                               addr.get(), (jbyte)scope, attrs.get(),
                               (jint)uid_counter);
}

static btrc_callbacks_t sBluetoothAvrcpCallbacks = {
    sizeof(sBluetoothAvrcpCallbacks),
    btavrcp_remote_features_callback,
    btavrcp_get_play_status_callback,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    btavrcp_get_element_attr_callback,
    btavrcp_register_notification_callback,
    btavrcp_volume_change_callback,
    btavrcp_passthrough_command_callback,
    btavrcp_set_addressed_player_callback,
    btavrcp_set_browsed_player_callback,
    btavrcp_get_folder_items_callback,
    btavrcp_change_path_callback,
    btavrcp_get_item_attr_callback,
    btavrcp_play_item_callback,
    btavrcp_get_total_num_items_callback,
    btavrcp_search_callback,
    btavrcp_add_to_play_list_callback,
};

static void classInitNative(JNIEnv* env, jclass clazz) {
  method_getRcFeatures =
      env->GetMethodID(clazz, "getRcFeaturesRequestFromNative", "([BI)V");
  method_getPlayStatus =
      env->GetMethodID(clazz, "getPlayStatusRequestFromNative", "([B)V");

  method_getElementAttr =
      env->GetMethodID(clazz, "getElementAttrRequestFromNative", "([BB[I)V");

  method_registerNotification = env->GetMethodID(
      clazz, "registerNotificationRequestFromNative", "([BII)V");

  method_volumeChangeCallback =
      env->GetMethodID(clazz, "volumeChangeRequestFromNative", "([BII)V");

  method_handlePassthroughCmd = env->GetMethodID(
      clazz, "handlePassthroughCmdRequestFromNative", "([BII)V");

  method_setAddressedPlayerCallback =
      env->GetMethodID(clazz, "setAddressedPlayerRequestFromNative", "([BI)V");

  method_setBrowsedPlayerCallback =
      env->GetMethodID(clazz, "setBrowsedPlayerRequestFromNative", "([BI)V");

  method_getFolderItemsCallback =
      env->GetMethodID(clazz, "getFolderItemsRequestFromNative", "([BBIIB[I)V");

  method_changePathCallback =
      env->GetMethodID(clazz, "changePathRequestFromNative", "([BB[B)V");

  method_getItemAttrCallback =
      env->GetMethodID(clazz, "getItemAttrRequestFromNative", "([BB[BIB[I)V");

  method_playItemCallback =
      env->GetMethodID(clazz, "playItemRequestFromNative", "([BBI[B)V");

  method_getTotalNumOfItemsCallback =
      env->GetMethodID(clazz, "getTotalNumOfItemsRequestFromNative", "([BB)V");

  method_searchCallback =
      env->GetMethodID(clazz, "searchRequestFromNative", "([BI[B)V");

  method_addToPlayListCallback =
      env->GetMethodID(clazz, "addToPlayListRequestFromNative", "([BB[BI)V");

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

static void initNative(JNIEnv* env, jobject object) {
  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == NULL) {
    ALOGE("Bluetooth module is not loaded");
    return;
  }

  if (sBluetoothAvrcpInterface != NULL) {
    ALOGW("Cleaning up Avrcp Interface before initializing...");
    sBluetoothAvrcpInterface->cleanup();
    sBluetoothAvrcpInterface = NULL;
  }

  if (mCallbacksObj != NULL) {
    ALOGW("Cleaning up Avrcp callback object");
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = NULL;
  }

  sBluetoothAvrcpInterface =
      (btrc_interface_t*)btInf->get_profile_interface(BT_PROFILE_AV_RC_ID);
  if (sBluetoothAvrcpInterface == NULL) {
    ALOGE("Failed to get Bluetooth Avrcp Interface");
    return;
  }

  bt_status_t status =
      sBluetoothAvrcpInterface->init(&sBluetoothAvrcpCallbacks);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed to initialize Bluetooth Avrcp, status: %d", status);
    sBluetoothAvrcpInterface = NULL;
    return;
  }

  mCallbacksObj = env->NewGlobalRef(object);
}

static void cleanupNative(JNIEnv* env, jobject object) {
  const bt_interface_t* btInf = getBluetoothInterface();
  if (btInf == NULL) {
    ALOGE("Bluetooth module is not loaded");
    return;
  }

  if (sBluetoothAvrcpInterface != NULL) {
    sBluetoothAvrcpInterface->cleanup();
    sBluetoothAvrcpInterface = NULL;
  }

  if (mCallbacksObj != NULL) {
    env->DeleteGlobalRef(mCallbacksObj);
    mCallbacksObj = NULL;
  }
}

static jboolean getPlayStatusRspNative(JNIEnv* env, jobject object,
                                       jbyteArray address, jint playStatus,
                                       jint songLen, jint songPos) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  bt_status_t status = sBluetoothAvrcpInterface->get_play_status_rsp(
      (bt_bdaddr_t*)addr, (btrc_play_status_t)playStatus, songLen, songPos);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed get_play_status_rsp, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean getElementAttrRspNative(JNIEnv* env, jobject object,
                                        jbyteArray address, jbyte numAttr,
                                        jintArray attrIds,
                                        jobjectArray textArray) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  if (numAttr > BTRC_MAX_ELEM_ATTR_SIZE) {
    ALOGE("get_element_attr_rsp: number of attributes exceed maximum");
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  btrc_element_attr_val_t* pAttrs = new btrc_element_attr_val_t[numAttr];
  if (!pAttrs) {
    ALOGE("get_element_attr_rsp: not have enough memeory");
    env->ReleaseByteArrayElements(address, addr, 0);
    return JNI_FALSE;
  }

  jint* attr = env->GetIntArrayElements(attrIds, NULL);
  if (!attr) {
    delete[] pAttrs;
    jniThrowIOException(env, EINVAL);
    env->ReleaseByteArrayElements(address, addr, 0);
    return JNI_FALSE;
  }

  int attr_cnt;
  for (attr_cnt = 0; attr_cnt < numAttr; ++attr_cnt) {
    pAttrs[attr_cnt].attr_id = attr[attr_cnt];
    ScopedLocalRef<jstring> text(
        env, (jstring)env->GetObjectArrayElement(textArray, attr_cnt));

    if (!copy_jstring(pAttrs[attr_cnt].text, BTRC_MAX_ATTR_STR_LEN, text.get(),
                      env)) {
      break;
    }
  }

  if (attr_cnt < numAttr) {
    delete[] pAttrs;
    env->ReleaseIntArrayElements(attrIds, attr, 0);
    ALOGE("%s: Failed to copy attributes", __func__);
    return JNI_FALSE;
  }

  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status =
      sBluetoothAvrcpInterface->get_element_attr_rsp(btAddr, numAttr, pAttrs);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed get_element_attr_rsp, status: %d", status);
  }

  delete[] pAttrs;
  env->ReleaseIntArrayElements(attrIds, attr, 0);
  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean getItemAttrRspNative(JNIEnv* env, jobject object,
                                     jbyteArray address, jint rspStatus,
                                     jbyte numAttr, jintArray attrIds,
                                     jobjectArray textArray) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  if (numAttr > BTRC_MAX_ELEM_ATTR_SIZE) {
    ALOGE("get_element_attr_rsp: number of attributes exceed maximum");
    return JNI_FALSE;
  }

  btrc_element_attr_val_t* pAttrs = new btrc_element_attr_val_t[numAttr];
  if (!pAttrs) {
    ALOGE("%s: not have enough memory", __func__);
    env->ReleaseByteArrayElements(address, addr, 0);
    return JNI_FALSE;
  }

  jint* attr = NULL;
  if (attrIds != NULL) {
    attr = env->GetIntArrayElements(attrIds, NULL);
    if (!attr) {
      delete[] pAttrs;
      jniThrowIOException(env, EINVAL);
      env->ReleaseByteArrayElements(address, addr, 0);
      return JNI_FALSE;
    }
  }

  for (int attr_cnt = 0; attr_cnt < numAttr; ++attr_cnt) {
    pAttrs[attr_cnt].attr_id = attr[attr_cnt];
    ScopedLocalRef<jstring> text(
        env, (jstring)env->GetObjectArrayElement(textArray, attr_cnt));

    if (!copy_jstring(pAttrs[attr_cnt].text, BTRC_MAX_ATTR_STR_LEN, text.get(),
                      env)) {
      rspStatus = BTRC_STS_INTERNAL_ERR;
      ALOGE("%s: Failed to copy attributes", __func__);
      break;
    }
  }

  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->get_item_attr_rsp(
      btAddr, (btrc_status_t)rspStatus, numAttr, pAttrs);
  if (status != BT_STATUS_SUCCESS)
    ALOGE("Failed get_item_attr_rsp, status: %d", status);

  if (pAttrs) delete[] pAttrs;
  if (attr) env->ReleaseIntArrayElements(attrIds, attr, 0);
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean registerNotificationRspPlayStatusNative(JNIEnv* env,
                                                        jobject object,
                                                        jint type,
                                                        jint playStatus) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  btrc_register_notification_t param;
  param.play_status = (btrc_play_status_t)playStatus;

  bt_status_t status = sBluetoothAvrcpInterface->register_notification_rsp(
      BTRC_EVT_PLAY_STATUS_CHANGED, (btrc_notification_type_t)type, &param);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed register_notification_rsp play status, status: %d", status);
  }

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean registerNotificationRspTrackChangeNative(JNIEnv* env,
                                                         jobject object,
                                                         jint type,
                                                         jbyteArray track) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* trk = env->GetByteArrayElements(track, NULL);
  if (!trk) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  btrc_register_notification_t param;
  for (int uid_idx = 0; uid_idx < BTRC_UID_SIZE; ++uid_idx) {
    param.track[uid_idx] = trk[uid_idx];
  }

  bt_status_t status = sBluetoothAvrcpInterface->register_notification_rsp(
      BTRC_EVT_TRACK_CHANGE, (btrc_notification_type_t)type, &param);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed register_notification_rsp track change, status: %d", status);
  }

  env->ReleaseByteArrayElements(track, trk, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean registerNotificationRspPlayPosNative(JNIEnv* env,
                                                     jobject object, jint type,
                                                     jint playPos) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  btrc_register_notification_t param;
  param.song_pos = (uint32_t)playPos;

  bt_status_t status = sBluetoothAvrcpInterface->register_notification_rsp(
      BTRC_EVT_PLAY_POS_CHANGED, (btrc_notification_type_t)type, &param);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed register_notification_rsp play position, status: %d", status);
  }

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean registerNotificationRspNowPlayingChangedNative(JNIEnv* env,
                                                               jobject object,
                                                               jint type) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  btrc_register_notification_t param;
  bt_status_t status = sBluetoothAvrcpInterface->register_notification_rsp(
      BTRC_EVT_NOW_PLAYING_CONTENT_CHANGED, (btrc_notification_type_t)type,
      &param);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed register_notification_rsp, nowPlaying Content status: %d",
          status);
  }
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean registerNotificationRspUIDsChangedNative(JNIEnv* env,
                                                         jobject object,
                                                         jint type,
                                                         jint uidCounter) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  btrc_register_notification_t param;
  param.uids_changed.uid_counter = (uint16_t)uidCounter;

  bt_status_t status = sBluetoothAvrcpInterface->register_notification_rsp(
      BTRC_EVT_UIDS_CHANGED, (btrc_notification_type_t)type, &param);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed register_notification_rsp, uids changed status: %d", status);
  }

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean registerNotificationRspAddrPlayerChangedNative(
    JNIEnv* env, jobject object, jint type, jint playerId, jint uidCounter) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  btrc_register_notification_t param;
  param.addr_player_changed.player_id = (uint16_t)playerId;
  param.addr_player_changed.uid_counter = (uint16_t)uidCounter;

  bt_status_t status = sBluetoothAvrcpInterface->register_notification_rsp(
      BTRC_EVT_ADDR_PLAYER_CHANGE, (btrc_notification_type_t)type, &param);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed register_notification_rsp address player changed status: %d",
          status);
  }

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean registerNotificationRspAvalPlayerChangedNative(JNIEnv* env,
                                                               jobject object,
                                                               jint type) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  btrc_register_notification_t param;
  bt_status_t status = sBluetoothAvrcpInterface->register_notification_rsp(
      BTRC_EVT_AVAL_PLAYER_CHANGE, (btrc_notification_type_t)type, &param);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE(
        "Failed register_notification_rsp available player changed status, "
        "status: %d",
        status);
  }

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setVolumeNative(JNIEnv* env, jobject object, jint volume) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  bt_status_t status = sBluetoothAvrcpInterface->set_volume((uint8_t)volume);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed set_volume, status: %d", status);
  }

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

/* native response for scope as Media player */
static jboolean mediaPlayerListRspNative(
    JNIEnv* env, jobject object, jbyteArray address, jint rspStatus,
    jint uidCounter, jbyte itemType, jint numItems, jbyteArray playerTypes,
    jintArray playerSubtypes, jbyteArray playStatusValues,
    jshortArray featureBitmask, jobjectArray textArray) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  jbyte *p_playerTypes = NULL, *p_PlayStatusValues = NULL;
  jshort* p_FeatBitMaskValues = NULL;
  jint* p_playerSubTypes = NULL;
  btrc_folder_items_t* p_items = NULL;
  if (rspStatus == BTRC_STS_NO_ERROR) {
    /* allocate memory */
    p_playerTypes = env->GetByteArrayElements(playerTypes, NULL);
    p_playerSubTypes = env->GetIntArrayElements(playerSubtypes, NULL);
    p_PlayStatusValues = env->GetByteArrayElements(playStatusValues, NULL);
    p_FeatBitMaskValues = env->GetShortArrayElements(featureBitmask, NULL);
    p_items = new btrc_folder_items_t[numItems];
    /* deallocate memory and return if allocation failed */
    if (!p_playerTypes || !p_playerSubTypes || !p_PlayStatusValues ||
        !p_FeatBitMaskValues || !p_items) {
      if (p_playerTypes)
        env->ReleaseByteArrayElements(playerTypes, p_playerTypes, 0);
      if (p_playerSubTypes)
        env->ReleaseIntArrayElements(playerSubtypes, p_playerSubTypes, 0);
      if (p_PlayStatusValues)
        env->ReleaseByteArrayElements(playStatusValues, p_PlayStatusValues, 0);
      if (p_FeatBitMaskValues)
        env->ReleaseShortArrayElements(featureBitmask, p_FeatBitMaskValues, 0);
      if (p_items) delete[] p_items;

      jniThrowIOException(env, EINVAL);
      ALOGE("%s: not have enough memory", __func__);
      return JNI_FALSE;
    }

    p_items->item_type = (uint8_t)itemType;

    /* copy list of media players along with other parameters */
    int itemIdx;
    for (itemIdx = 0; itemIdx < numItems; ++itemIdx) {
      p_items[itemIdx].player.player_id = (uint16_t)(itemIdx + 1);
      p_items[itemIdx].player.major_type = p_playerTypes[itemIdx];
      p_items[itemIdx].player.sub_type = p_playerSubTypes[itemIdx];
      p_items[itemIdx].player.play_status = p_PlayStatusValues[itemIdx];
      p_items[itemIdx].player.charset_id = BTRC_CHARSET_ID_UTF8;

      ScopedLocalRef<jstring> text(
          env, (jstring)env->GetObjectArrayElement(textArray, itemIdx));
      /* copy player name */
      if (!copy_jstring(p_items[itemIdx].player.name, BTRC_MAX_ATTR_STR_LEN,
                        text.get(), env))
        break;

      /* Feature bit mask is 128-bit value each */
      for (int InnCnt = 0; InnCnt < 16; InnCnt++) {
        p_items[itemIdx].player.features[InnCnt] =
            (uint8_t)p_FeatBitMaskValues[(itemIdx * 16) + InnCnt];
      }
    }

    /* failed to copy list of media players */
    if (itemIdx < numItems) {
      rspStatus = BTRC_STS_INTERNAL_ERR;
      ALOGE("%s: Failed to copy Media player attributes", __func__);
    }
  }

  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->get_folder_items_list_rsp(
      btAddr, (btrc_status_t)rspStatus, uidCounter, numItems, p_items);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed get_folder_items_list_rsp, status: %d", status);
  }

  /* release allocated memory */
  if (p_items) delete[] p_items;
  if (p_playerTypes)
    env->ReleaseByteArrayElements(playerTypes, p_playerTypes, 0);
  if (p_playerSubTypes)
    env->ReleaseIntArrayElements(playerSubtypes, p_playerSubTypes, 0);
  if (p_PlayStatusValues)
    env->ReleaseByteArrayElements(playStatusValues, p_PlayStatusValues, 0);
  if (p_FeatBitMaskValues) {
    env->ReleaseShortArrayElements(featureBitmask, p_FeatBitMaskValues, 0);
  }
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean getFolderItemsRspNative(
    JNIEnv* env, jobject object, jbyteArray address, jint rspStatus,
    jshort uidCounter, jbyte scope, jint numItems, jbyteArray folderType,
    jbyteArray playable, jbyteArray itemType, jbyteArray itemUidArray,
    jobjectArray displayNameArray, jintArray numAttrs, jintArray attributesIds,
    jobjectArray attributesArray) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  jbyte *p_playable = NULL, *p_item_uid = NULL;
  jbyte* p_item_types = NULL; /* Folder or Media Item */
  jint* p_attributesIds = NULL;
  jbyte* p_folder_types =
      NULL; /* Folder properties like Album/Genre/Artists etc */
  jint* p_num_attrs = NULL;
  btrc_folder_items_t* p_items = NULL;
  /* none of the parameters should be null when no error */
  if (rspStatus == BTRC_STS_NO_ERROR) {
    /* allocate memory to each rsp item */
    if (folderType != NULL)
      p_folder_types = env->GetByteArrayElements(folderType, NULL);
    if (playable != NULL)
      p_playable = env->GetByteArrayElements(playable, NULL);
    if (itemType != NULL)
      p_item_types = env->GetByteArrayElements(itemType, NULL);
    if (NULL != numAttrs)
      p_num_attrs = env->GetIntArrayElements(numAttrs, NULL);
    if (NULL != attributesIds)
      p_attributesIds = env->GetIntArrayElements(attributesIds, NULL);
    if (itemUidArray != NULL)
      p_item_uid = (jbyte*)env->GetByteArrayElements(itemUidArray, NULL);

    p_items = new btrc_folder_items_t[numItems];

    /* if memory alloc failed, release memory */
    if (p_items && p_folder_types && p_playable && p_item_types && p_item_uid &&
        /* attributes can be null if remote requests 0 attributes */
        ((numAttrs != NULL && p_num_attrs) || (!numAttrs && !p_num_attrs)) &&
        ((attributesIds != NULL && p_attributesIds) ||
         (!attributesIds && !p_attributesIds))) {
      memset(p_items, 0, sizeof(btrc_folder_items_t) * numItems);
      if (scope == BTRC_SCOPE_FILE_SYSTEM || scope == BTRC_SCOPE_SEARCH ||
          scope == BTRC_SCOPE_NOW_PLAYING) {
        int attribCopiedIndex = 0;
        for (int item_idx = 0; item_idx < numItems; item_idx++) {
          if (BTRC_ITEM_FOLDER == p_item_types[item_idx]) {
            btrc_folder_items_t* pitem = &p_items[item_idx];

            memcpy(pitem->folder.uid, p_item_uid + item_idx * BTRC_UID_SIZE,
                   BTRC_UID_SIZE);
            pitem->item_type = (uint8_t)BTRC_ITEM_FOLDER;
            pitem->folder.charset_id = BTRC_CHARSET_ID_UTF8;
            pitem->folder.type = p_folder_types[item_idx];
            pitem->folder.playable = p_playable[item_idx];

            ScopedLocalRef<jstring> text(
                env, (jstring)env->GetObjectArrayElement(displayNameArray,
                                                         item_idx));
            if (!copy_jstring(pitem->folder.name, BTRC_MAX_ATTR_STR_LEN,
                              text.get(), env)) {
              rspStatus = BTRC_STS_INTERNAL_ERR;
              ALOGE("%s: failed to copy display name of folder item", __func__);
              break;
            }
          } else if (BTRC_ITEM_MEDIA == p_item_types[item_idx]) {
            btrc_folder_items_t* pitem = &p_items[item_idx];
            memcpy(pitem->media.uid, p_item_uid + item_idx * BTRC_UID_SIZE,
                   BTRC_UID_SIZE);

            pitem->item_type = (uint8_t)BTRC_ITEM_MEDIA;
            pitem->media.charset_id = BTRC_CHARSET_ID_UTF8;
            pitem->media.type = BTRC_MEDIA_TYPE_AUDIO;
            pitem->media.num_attrs =
                (p_num_attrs != NULL) ? p_num_attrs[item_idx] : 0;

            ScopedLocalRef<jstring> text(
                env, (jstring)env->GetObjectArrayElement(displayNameArray,
                                                         item_idx));
            if (!copy_jstring(pitem->media.name, BTRC_MAX_ATTR_STR_LEN,
                              text.get(), env)) {
              rspStatus = BTRC_STS_INTERNAL_ERR;
              ALOGE("%s: failed to copy display name of media item", __func__);
              break;
            }

            /* copy item attributes */
            if (!copy_item_attributes(env, object, pitem, p_attributesIds,
                                      attributesArray, item_idx,
                                      attribCopiedIndex)) {
              ALOGE("%s: error in copying attributes of item = %s", __func__,
                    pitem->media.name);
              rspStatus = BTRC_STS_INTERNAL_ERR;
              break;
            }
            attribCopiedIndex += pitem->media.num_attrs;
          }
        }
      }
    } else {
      rspStatus = BTRC_STS_INTERNAL_ERR;
      ALOGE("%s: unable to allocate memory", __func__);
    }
  }

  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->get_folder_items_list_rsp(
      btAddr, (btrc_status_t)rspStatus, uidCounter, numItems, p_items);
  if (status != BT_STATUS_SUCCESS)
    ALOGE("Failed get_folder_items_list_rsp, status: %d", status);

  /* Release allocated memory for all attributes in each media item */
  if (p_items) cleanup_items(p_items, numItems);

  /* Release allocated memory  */
  if (p_folder_types)
    env->ReleaseByteArrayElements(folderType, p_folder_types, 0);
  if (p_playable) env->ReleaseByteArrayElements(playable, p_playable, 0);
  if (p_item_types) env->ReleaseByteArrayElements(itemType, p_item_types, 0);
  if (p_num_attrs) env->ReleaseIntArrayElements(numAttrs, p_num_attrs, 0);
  if (p_attributesIds)
    env->ReleaseIntArrayElements(attributesIds, p_attributesIds, 0);
  if (p_item_uid) env->ReleaseByteArrayElements(itemUidArray, p_item_uid, 0);
  if (p_items) delete[] p_items;
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setAddressedPlayerRspNative(JNIEnv* env, jobject object,
                                            jbyteArray address,
                                            jint rspStatus) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->set_addressed_player_rsp(
      btAddr, (btrc_status_t)rspStatus);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed set_addressed_player_rsp, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean setBrowsedPlayerRspNative(JNIEnv* env, jobject object,
                                          jbyteArray address, jint rspStatus,
                                          jbyte depth, jint numItems,
                                          jobjectArray textArray) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  btrc_br_folder_name_t* p_folders = NULL;
  if (rspStatus == BTRC_STS_NO_ERROR) {
    if (depth > 0) {
      p_folders = new btrc_br_folder_name_t[depth];
    }

    for (int folder_idx = 0; folder_idx < depth; folder_idx++) {
      /* copy folder names */
      ScopedLocalRef<jstring> text(
          env, (jstring)env->GetObjectArrayElement(textArray, folder_idx));

      if (!copy_jstring(p_folders[folder_idx].p_str, BTRC_MAX_ATTR_STR_LEN,
                        text.get(), env)) {
        rspStatus = BTRC_STS_INTERNAL_ERR;
        delete[] p_folders;
        env->ReleaseByteArrayElements(address, addr, 0);
        ALOGE("%s: Failed to copy folder name", __func__);
        return JNI_FALSE;
      }

      p_folders[folder_idx].str_len =
          strlen((char*)p_folders[folder_idx].p_str);
    }
  }

  uint8_t folder_depth =
      depth; /* folder_depth is 0 if current folder is root */
  uint16_t charset_id = BTRC_CHARSET_ID_UTF8;
  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->set_browsed_player_rsp(
      btAddr, (btrc_status_t)rspStatus, numItems, charset_id, folder_depth,
      p_folders);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("%s: Failed set_browsed_player_rsp, status: %d", __func__, status);
  }

  if (depth > 0) {
    delete[] p_folders;
  }

  env->ReleaseByteArrayElements(address, addr, 0);
  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean changePathRspNative(JNIEnv* env, jobject object,
                                    jbyteArray address, jint rspStatus,
                                    jint numItems) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  uint32_t nItems = (uint32_t)numItems;
  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->change_path_rsp(
      btAddr, (btrc_status_t)rspStatus, (uint32_t)nItems);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed change_path_rsp, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean searchRspNative(JNIEnv* env, jobject object, jbyteArray address,
                                jint rspStatus, jint uidCounter,
                                jint numItems) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  uint32_t nItems = (uint32_t)numItems;
  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->search_rsp(
      btAddr, (btrc_status_t)rspStatus, (uint32_t)uidCounter, (uint32_t)nItems);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed search_rsp, status: %d", status);
  }

  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean playItemRspNative(JNIEnv* env, jobject object,
                                  jbyteArray address, jint rspStatus) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status =
      sBluetoothAvrcpInterface->play_item_rsp(btAddr, (btrc_status_t)rspStatus);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed play_item_rsp, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean getTotalNumOfItemsRspNative(JNIEnv* env, jobject object,
                                            jbyteArray address, jint rspStatus,
                                            jint uidCounter, jint numItems) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  uint32_t nItems = (uint32_t)numItems;
  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->get_total_num_of_items_rsp(
      btAddr, (btrc_status_t)rspStatus, (uint32_t)uidCounter, (uint32_t)nItems);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed get_total_num_of_items_rsp, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static jboolean addToNowPlayingRspNative(JNIEnv* env, jobject object,
                                         jbyteArray address, jint rspStatus) {
  if (!sBluetoothAvrcpInterface) {
    ALOGE("%s: sBluetoothAvrcpInterface is null", __func__);
    return JNI_FALSE;
  }

  jbyte* addr = env->GetByteArrayElements(address, NULL);
  if (!addr) {
    jniThrowIOException(env, EINVAL);
    return JNI_FALSE;
  }

  bt_bdaddr_t* btAddr = (bt_bdaddr_t*)addr;
  bt_status_t status = sBluetoothAvrcpInterface->add_to_now_playing_rsp(
      btAddr, (btrc_status_t)rspStatus);
  if (status != BT_STATUS_SUCCESS) {
    ALOGE("Failed add_to_now_playing_rsp, status: %d", status);
  }
  env->ReleaseByteArrayElements(address, addr, 0);

  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
}

static JNINativeMethod sMethods[] = {
    {"classInitNative", "()V", (void*)classInitNative},
    {"initNative", "()V", (void*)initNative},
    {"cleanupNative", "()V", (void*)cleanupNative},
    {"getPlayStatusRspNative", "([BIII)Z", (void*)getPlayStatusRspNative},
    {"getElementAttrRspNative", "([BB[I[Ljava/lang/String;)Z",
     (void*)getElementAttrRspNative},
    {"registerNotificationRspPlayStatusNative", "(II)Z",
     (void*)registerNotificationRspPlayStatusNative},
    {"registerNotificationRspTrackChangeNative", "(I[B)Z",
     (void*)registerNotificationRspTrackChangeNative},
    {"registerNotificationRspPlayPosNative", "(II)Z",
     (void*)registerNotificationRspPlayPosNative},
    {"setVolumeNative", "(I)Z", (void*)setVolumeNative},

    {"setAddressedPlayerRspNative", "([BI)Z",
     (void*)setAddressedPlayerRspNative},

    {"setBrowsedPlayerRspNative", "([BIBI[Ljava/lang/String;)Z",
     (void*)setBrowsedPlayerRspNative},

    {"mediaPlayerListRspNative", "([BIIBI[B[I[B[S[Ljava/lang/String;)Z",
     (void*)mediaPlayerListRspNative},

    {"getFolderItemsRspNative",
     "([BISBI[B[B[B[B[Ljava/lang/String;[I[I[Ljava/lang/String;)Z",
     (void*)getFolderItemsRspNative},

    {"changePathRspNative", "([BII)Z", (void*)changePathRspNative},

    {"getItemAttrRspNative", "([BIB[I[Ljava/lang/String;)Z",
     (void*)getItemAttrRspNative},

    {"playItemRspNative", "([BI)Z", (void*)playItemRspNative},

    {"getTotalNumOfItemsRspNative", "([BIII)Z",
     (void*)getTotalNumOfItemsRspNative},

    {"searchRspNative", "([BIII)Z", (void*)searchRspNative},

    {"addToNowPlayingRspNative", "([BI)Z", (void*)addToNowPlayingRspNative},

    {"registerNotificationRspAddrPlayerChangedNative", "(III)Z",
     (void*)registerNotificationRspAddrPlayerChangedNative},

    {"registerNotificationRspAvalPlayerChangedNative", "(I)Z",
     (void*)registerNotificationRspAvalPlayerChangedNative},

    {"registerNotificationRspUIDsChangedNative", "(II)Z",
     (void*)registerNotificationRspUIDsChangedNative},

    {"registerNotificationRspNowPlayingChangedNative", "(I)Z",
     (void*)registerNotificationRspNowPlayingChangedNative}};

int register_com_android_bluetooth_avrcp(JNIEnv* env) {
  return jniRegisterNativeMethods(env, "com/android/bluetooth/avrcp/Avrcp",
                                  sMethods, NELEM(sMethods));
}

/* Helper function to copy attributes of item.
 * Assumes that all items in response have same number of attributes
 *
 * returns true on succes, false otherwise.
*/
static bool copy_item_attributes(JNIEnv* env, jobject object,
                                 btrc_folder_items_t* pitem,
                                 jint* p_attributesIds,
                                 jobjectArray attributesArray, int item_idx,
                                 int attribCopiedIndex) {
  bool success = true;

  /* copy attributes of the item */
  if (0 < pitem->media.num_attrs) {
    int num_attrs = pitem->media.num_attrs;
    ALOGI("%s num_attr = %d", __func__, num_attrs);
    pitem->media.p_attrs = new btrc_element_attr_val_t[num_attrs];
    if (!pitem->media.p_attrs) {
      return false;
    }

    for (int tempAtrCount = 0; tempAtrCount < pitem->media.num_attrs;
         ++tempAtrCount) {
      pitem->media.p_attrs[tempAtrCount].attr_id =
          p_attributesIds[attribCopiedIndex + tempAtrCount];

      ScopedLocalRef<jstring> text(
          env, (jstring)env->GetObjectArrayElement(
                   attributesArray, attribCopiedIndex + tempAtrCount));

      if (!copy_jstring(pitem->media.p_attrs[tempAtrCount].text,
                        BTRC_MAX_ATTR_STR_LEN, text.get(), env)) {
        success = false;
        ALOGE("%s: failed to copy attributes", __func__);
        break;
      }
    }
  }
  return success;
}

/* Helper function to copy String data from java to native
 *
 * returns true on succes, false otherwise
 */
static bool copy_jstring(uint8_t* str, int maxBytes, jstring jstr,
                         JNIEnv* env) {
  if (str == NULL || jstr == NULL || env == NULL) return false;

  memset(str, 0, maxBytes);
  const char* p_str = env->GetStringUTFChars(jstr, NULL);
  size_t len = strnlen(p_str, maxBytes - 1);
  memcpy(str, p_str, len);

  env->ReleaseStringUTFChars(jstr, p_str);
  return true;
}

/* Helper function to cleanup items */
static void cleanup_items(btrc_folder_items_t* p_items, int numItems) {
  for (int item_idx = 0; item_idx < numItems; item_idx++) {
    /* release memory for attributes in case item is media item */
    if ((BTRC_ITEM_MEDIA == p_items[item_idx].item_type) &&
        p_items[item_idx].media.p_attrs != NULL)
      delete[] p_items[item_idx].media.p_attrs;
  }
}
}
