com_android_bluetooth_avrcp_controller.cpp revision 2116dbf94fbc00da999ac629c78627983f599a26
1066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood/*
2e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * Copyright (C) 2016 The Android Open Source Project
3066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood *
4066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License");
5066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * you may not use this file except in compliance with the License.
6066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * You may obtain a copy of the License at
7066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood *
8066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood *      http://www.apache.org/licenses/LICENSE-2.0
9066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood *
10066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * Unless required by applicable law or agreed to in writing, software
11066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS,
12066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * See the License for the specific language governing permissions and
14066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood * limitations under the License.
15066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood */
16066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
17066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood#define LOG_TAG "BluetoothAvrcpControllerJni"
18066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
19066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood#define LOG_NDEBUG 0
20066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
21dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen#include "android_runtime/AndroidRuntime.h"
22066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood#include "com_android_bluetooth.h"
23066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood#include "hardware/bt_rc.h"
24066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood#include "utils/Log.h"
25066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
26066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood#include <string.h>
27066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
28066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodnamespace android {
29066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic jmethodID method_handlePassthroughRsp;
30066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic jmethodID method_onConnectionStateChanged;
31de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_getRcFeatures;
32de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_setplayerappsettingrsp;
33de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handleplayerappsetting;
34de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handleplayerappsettingchanged;
35de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handleSetAbsVolume;
36de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handleRegisterNotificationAbsVol;
37de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handletrackchanged;
38de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handleplaypositionchanged;
39de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handleplaystatuschanged;
402df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jmethodID method_handleGetFolderItemsRsp;
412df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jmethodID method_handleGetPlayerItemsRsp;
42de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic jmethodID method_handleGroupNavigationRsp;
432df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jmethodID method_createFromNativeMediaItem;
442df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jmethodID method_createFromNativeFolderItem;
452df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jmethodID method_createFromNativePlayerItem;
462df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jmethodID method_handleChangeFolderRsp;
472df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jmethodID method_handleSetBrowsedPlayerRsp;
48a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwalstatic jmethodID method_handleSetAddressedPlayerRsp;
49de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
502df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jclass class_MediaBrowser_MediaItem;
512df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jclass class_AvrcpPlayer;
52066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
53dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic const btrc_ctrl_interface_t* sBluetoothAvrcpInterface = NULL;
542df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwalstatic jobject sCallbacksObj = NULL;
55066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
56dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_passthrough_response_callback(bt_bdaddr_t* bd_addr, int id,
57dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                  int pressed) {
58dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: id: %d, pressed: %d", __func__, id, pressed);
59dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
60dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
61066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
622116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
632116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
642116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
652116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr for passthrough response");
662116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
672116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
68066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
692116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
702116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
71dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handlePassthroughRsp,
72479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               (jint)id, (jint)pressed, addr.get());
73066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
74066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
75de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwalstatic void btavrcp_groupnavigation_response_callback(int id, int pressed) {
76dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
77dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
78dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
79de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
80dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGroupNavigationRsp,
81dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)id, (jint)pressed);
82de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
83de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
84dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_connection_state_callback(bool rc_connect, bool br_connect,
85dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                              bt_bdaddr_t* bd_addr) {
86dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: conn state: rc: %d br: %d", __func__, rc_connect, br_connect);
87dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
88dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
89dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
902116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
912116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
922116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
932116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr for connection state");
942116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
952116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
96dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
972116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
982116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
99dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_onConnectionStateChanged,
100dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jboolean)rc_connect, (jboolean)br_connect,
101479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get());
102066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
103066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
104dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_get_rcfeatures_callback(bt_bdaddr_t* bd_addr,
105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                            int features) {
106dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
107dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
109dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1102116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
1112116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
1122116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1132116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr ");
1142116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
1152116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
116dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1172116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
1182116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
119479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_getRcFeatures, addr.get(),
120dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)features);
121de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
122de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
123dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_setplayerapplicationsetting_rsp_callback(
124dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    bt_bdaddr_t* bd_addr, uint8_t accepted) {
125dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
126dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
127dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
128dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1292116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
1302116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
1312116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1322116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr ");
1332116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
1342116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
135dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1362116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
1372116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
138dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_setplayerappsettingrsp,
139479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jint)accepted);
140de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
141de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
142dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_playerapplicationsetting_callback(
143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    bt_bdaddr_t* bd_addr, uint8_t num_attr, btrc_player_app_attr_t* app_attrs,
144dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    uint8_t num_ext_attr, btrc_player_app_ext_attr_t* ext_attrs) {
145dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
146dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
147dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
148dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1492116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
1502116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
1512116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr ");
1532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
1542116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
1552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
1562116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
157dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* TODO ext attrs
158dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * Flattening defined attributes: <id,num_values,values[]>
159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jint arraylen = 0;
161dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < num_attr; i++) {
162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    /*2 bytes for id and num */
163dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    arraylen += 2 + app_attrs[i].num_val;
164dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
165dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV(" arraylen %d", arraylen);
166dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
167479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> playerattribs(
168479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(arraylen));
169479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!playerattribs.get()) {
170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to new jbyteArray playerattribs ");
171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
172dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
173dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
174dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0, k = 0; (i < num_attr) && (k < arraylen); i++) {
175479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
176dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(app_attrs[i].attr_id));
177dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
178479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
179dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(app_attrs[i].num_val));
180dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
181479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k,
182479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                     app_attrs[i].num_val,
183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)(app_attrs[i].attr_val));
184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k = k + app_attrs[i].num_val;
185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
186dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplayerappsetting,
187479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), playerattribs.get(), (jint)arraylen);
188de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
189de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
190dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_playerapplicationsetting_changed_callback(
191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    bt_bdaddr_t* bd_addr, btrc_player_settings_t* p_vals) {
192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
193dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
194dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
195dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1962116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
1972116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
1982116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1992116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
2002116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2012116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
2022116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
2032116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
204dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
205dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int arraylen = p_vals->num_attr * 2;
206479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> playerattribs(
207479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(arraylen));
208479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!playerattribs.get()) {
209dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to new jbyteArray playerattribs ");
210dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
211dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
212dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /*
213dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * Flatening format: <id,val>
214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
215dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0, k = 0; (i < p_vals->num_attr) && (k < arraylen); i++) {
216479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(p_vals->attr_ids[i]));
218dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
219479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(p_vals->attr_values[i]));
221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
223dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj,
224479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_handleplayerappsettingchanged, addr.get(),
225479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               playerattribs.get(), (jint)arraylen);
226de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
227de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
228dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_set_abs_vol_cmd_callback(bt_bdaddr_t* bd_addr,
229dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                             uint8_t abs_vol, uint8_t label) {
230dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
231dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
232dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
233dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2342116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
2352116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
2362116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2372116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
2382116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2392116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
240dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2412116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
2422116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
243479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetAbsVolume,
244479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)abs_vol, (jbyte)label);
245de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
246de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
247dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_register_notification_absvol_callback(bt_bdaddr_t* bd_addr,
248dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                          uint8_t label) {
249dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
250dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
251dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
252dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
2542116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
2552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2562116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
2572116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2582116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
259dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2602116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
2612116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
262dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj,
263479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_handleRegisterNotificationAbsVol,
264479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)label);
265de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
266de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
267dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_track_changed_callback(bt_bdaddr_t* bd_addr,
268dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                           uint8_t num_attr,
269dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                           btrc_element_attr_val_t* p_attrs) {
270dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /*
271dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * byteArray will be formatted like this: id,len,string
272dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * Assuming text feild to be null terminated.
273dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
274dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
275dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
277dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2782116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
2792116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
2802116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2812116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
2822116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2832116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
284dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
285479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jintArray> attribIds(sCallbackEnv.get(),
286479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                      sCallbackEnv->NewIntArray(num_attr));
287479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!attribIds.get()) {
288dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE(" failed to set new array for attribIds");
289dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
290dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
2912116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
2922116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
293dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
294dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass strclazz = sCallbackEnv->FindClass("java/lang/String");
295479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> stringArray(
296479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
297479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv->NewObjectArray((jint)num_attr, strclazz, 0));
298479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!stringArray.get()) {
299dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE(" failed to get String array");
300dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
302dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
303dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (jint i = 0; i < num_attr; i++) {
304479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jstring> str(
305479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv.get(),
306479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->NewStringUTF((char*)(p_attrs[i].text)));
307479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (!str.get()) {
308dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("Unable to get str");
309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return;
310dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
311479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetIntArrayRegion(attribIds.get(), i, 1,
312dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    (jint*)&(p_attrs[i].attr_id));
313479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetObjectArrayElement(stringArray.get(), i, str.get());
314dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
315dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
316479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handletrackchanged,
317479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)(num_attr), attribIds.get(),
318479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               stringArray.get());
319de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
320de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
321dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_play_position_changed_callback(bt_bdaddr_t* bd_addr,
322dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                   uint32_t song_len,
323dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                   uint32_t song_pos) {
324dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
325dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
326dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
327dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
3282116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
3292116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
3302116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3312116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
3322116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3332116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
3342116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
3352116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
336dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaypositionchanged,
337479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jint)(song_len), (jint)song_pos);
338de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
339de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
340dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_play_status_changed_callback(
341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    bt_bdaddr_t* bd_addr, btrc_play_status_t play_status) {
342dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
345dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
3462116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
3472116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)));
3482116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3492116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
3502116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3512116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
3522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(bt_bdaddr_t),
3532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
354dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaystatuschanged,
355479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)play_status);
356dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen}
357de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
358dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_get_folder_items_callback(
359dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    bt_bdaddr_t* bd_addr, btrc_status_t status,
360dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    const btrc_folder_items_t* folder_items, uint8_t count) {
361dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* Folder items are list of items that can be either BTRC_ITEM_PLAYER
362dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * BTRC_ITEM_MEDIA, BTRC_ITEM_FOLDER. Here we translate them to their java
363dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * counterparts by calling the java constructor for each of the items.
364dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
365dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s count %d", __func__, count);
366dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
367dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
368dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
369dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // Inspect if the first element is a folder/item or player listing. They are
370dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // always exclusive.
371dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bool isPlayerListing =
372dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      count > 0 && (folder_items[0].item_type == BTRC_ITEM_PLAYER);
373dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
374dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // Initialize arrays for Folder OR Player listing.
375479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> itemArray(sCallbackEnv.get(), NULL);
376dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (isPlayerListing) {
377479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    itemArray.reset(
378479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->NewObjectArray((jint)count, class_AvrcpPlayer, 0));
379dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
380479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    itemArray.reset(sCallbackEnv->NewObjectArray(
381479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        (jint)count, class_MediaBrowser_MediaItem, 0));
382479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  }
383479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!itemArray.get()) {
384479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ALOGE("%s itemArray allocation failed.", __func__);
385479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    return;
386dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
387dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < count; i++) {
388dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    const btrc_folder_items_t* item = &(folder_items[i]);
389dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGV("%s item type %d", __func__, item->item_type);
390dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    switch (item->item_type) {
391dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      case BTRC_ITEM_MEDIA: {
392dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse name
393479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jstring> mediaName(
394479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
395479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewStringUTF((const char*)item->media.name));
396479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!mediaName.get()) {
397479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate media name string!", __func__);
398479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
399479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
400dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse UID
401479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jbyteArray> uidByteArray(
402479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
403479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewByteArray(sizeof(uint8_t) * BTRC_UID_SIZE));
404479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!uidByteArray.get()) {
405479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate uid array!", __func__);
406479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
407479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
408479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetByteArrayRegion(uidByteArray.get(), 0,
409dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         BTRC_UID_SIZE * sizeof(uint8_t),
410dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         (jbyte*)item->media.uid);
411dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
412dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse Attrs
413479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jintArray> attrIdArray(
414479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
415479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewIntArray(item->media.num_attrs));
416479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!attrIdArray.get()) {
417479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate attr id array!", __func__);
418479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
419479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
420479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobjectArray> attrValArray(
421479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
422479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewObjectArray(
423479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                item->media.num_attrs,
424479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbackEnv->FindClass("java/lang/String"), 0));
425479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!attrValArray.get()) {
426479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate attr val array!", __func__);
427479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
428479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
429dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
430dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        for (int j = 0; j < item->media.num_attrs; j++) {
431dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          sCallbackEnv->SetIntArrayRegion(
432479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              attrIdArray.get(), j, 1,
433479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              (jint*)&(item->media.p_attrs[j].attr_id));
434479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ScopedLocalRef<jstring> attrValStr(
435479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              sCallbackEnv.get(),
436479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              sCallbackEnv->NewStringUTF((char*)(item->media.p_attrs[j].text)));
437479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          if (!uidByteArray.get()) {
438479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            ALOGE("%s can't allocate uid array!", __func__);
439479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            return;
440479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          }
441479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          sCallbackEnv->SetObjectArrayElement(attrValArray.get(), j,
442479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                              attrValStr.get());
443dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        }
444066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
445479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobject> mediaObj(
446479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
447479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            (jobject)sCallbackEnv->CallObjectMethod(
448479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbacksObj, method_createFromNativeMediaItem,
449479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                uidByteArray.get(), (jint)item->media.type, mediaName.get(),
450479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                attrIdArray.get(), attrValArray.get()));
451479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!mediaObj.get()) {
452479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s failed to creae MediaItem for type ITEM_MEDIA", __func__);
453dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          return;
4542df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal        }
455479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetObjectArrayElement(itemArray.get(), i, mediaObj.get());
456dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        break;
457dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      }
458dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
459dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      case BTRC_ITEM_FOLDER: {
460dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse name
461479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jstring> folderName(
462479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
463479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewStringUTF((const char*)item->folder.name));
464479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!folderName.get()) {
465479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate folder name string!", __func__);
466479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
467479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
468dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse UID
469479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jbyteArray> uidByteArray(
470479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
471479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewByteArray(sizeof(uint8_t) * BTRC_UID_SIZE));
472479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!uidByteArray.get()) {
473479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate uid array!", __func__);
474479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
475479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
476479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetByteArrayRegion(uidByteArray.get(), 0,
477dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         BTRC_UID_SIZE * sizeof(uint8_t),
478dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         (jbyte*)item->folder.uid);
479dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
480479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobject> folderObj(
481479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
482479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            (jobject)sCallbackEnv->CallObjectMethod(
483479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbacksObj, method_createFromNativeFolderItem,
484479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                uidByteArray.get(), (jint)item->folder.type, folderName.get(),
485479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                (jint)item->folder.playable));
486479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!folderObj.get()) {
487479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s failed to create MediaItem for type ITEM_FOLDER", __func__);
488dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          return;
4892df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal        }
490479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetObjectArrayElement(itemArray.get(), i,
491479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                            folderObj.get());
492dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        break;
493dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      }
494dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
495dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      case BTRC_ITEM_PLAYER: {
496dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse name
497dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        isPlayerListing = true;
498dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        jint id = (jint)item->player.player_id;
499dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        jint playerType = (jint)item->player.major_type;
500dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        jint playStatus = (jint)item->player.play_status;
501479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jbyteArray> featureBitArray(
502479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
503479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewByteArray(BTRC_FEATURE_BIT_MASK_SIZE *
504479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                       sizeof(uint8_t)));
505479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!featureBitArray.get()) {
506dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          ALOGE("%s failed to allocate featureBitArray", __func__);
507dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          return;
5082df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal        }
509dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        sCallbackEnv->SetByteArrayRegion(
510479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            featureBitArray.get(), 0,
511479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sizeof(uint8_t) * BTRC_FEATURE_BIT_MASK_SIZE,
512dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen            (jbyte*)item->player.features);
513479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jstring> playerName(
514479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
515479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewStringUTF((const char*)item->player.name));
516479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!playerName.get()) {
517479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate player name string!", __func__);
518479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
519479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
520479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobject> playerObj(
521479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
522479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            (jobject)sCallbackEnv->CallObjectMethod(
523479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbacksObj, method_createFromNativePlayerItem, id,
524479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                playerName.get(), featureBitArray.get(), playStatus,
525479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                playerType));
526479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!playerObj.get()) {
527479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s failed to create AvrcpPlayer from ITEM_PLAYER", __func__);
528479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
529479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
530479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetObjectArrayElement(itemArray.get(), i,
531479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                            playerObj.get());
532dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        break;
533dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      }
534dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
535dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      default:
536dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        ALOGE("%s cannot understand type %d", __func__, item->item_type);
5372df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    }
538dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
539dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
540dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (isPlayerListing) {
541dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGetPlayerItemsRsp,
542479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                 itemArray.get());
543dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
544dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGetFolderItemsRsp,
545479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                 status, itemArray.get());
546dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
5472df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
5482df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
549dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_change_path_callback(bt_bdaddr_t* bd_addr, uint8_t count) {
550dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s count %d", __func__, count);
551dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
552dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
5532df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
554dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleChangeFolderRsp,
555dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)count);
5562df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
5572df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
558dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_set_browsed_player_callback(bt_bdaddr_t* bd_addr,
559dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                uint8_t num_items,
560dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                uint8_t depth) {
561dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s items %d depth %d", __func__, num_items, depth);
562dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
563dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
5642df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
565dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetBrowsedPlayerRsp,
566dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)num_items, (jint)depth);
5672df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
5682df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
569dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_set_addressed_player_callback(bt_bdaddr_t* bd_addr,
570dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                  uint8_t status) {
571dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s status %d", __func__, status);
572a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
573dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
574dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
575a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
576dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(
577dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sCallbacksObj, method_handleSetAddressedPlayerRsp, (jint)status);
578a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal}
579a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
580066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic btrc_ctrl_callbacks_t sBluetoothAvrcpCallbacks = {
581066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood    sizeof(sBluetoothAvrcpCallbacks),
582066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood    btavrcp_passthrough_response_callback,
583de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_groupnavigation_response_callback,
584de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_connection_state_callback,
585de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_get_rcfeatures_callback,
586de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_setplayerapplicationsetting_rsp_callback,
587de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_playerapplicationsetting_callback,
588de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_playerapplicationsetting_changed_callback,
589de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_set_abs_vol_cmd_callback,
590de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_register_notification_absvol_callback,
591de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_track_changed_callback,
592de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_play_position_changed_callback,
5932df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    btavrcp_play_status_changed_callback,
5942df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    btavrcp_get_folder_items_callback,
5952df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    btavrcp_change_path_callback,
596a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal    btavrcp_set_browsed_player_callback,
597dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    btavrcp_set_addressed_player_callback};
598066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
599066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic void classInitNative(JNIEnv* env, jclass clazz) {
600dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handlePassthroughRsp =
601dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handlePassthroughRsp", "(II[B)V");
602dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
603dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleGroupNavigationRsp =
604dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleGroupNavigationRsp", "(II)V");
605dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
606dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_onConnectionStateChanged =
607dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onConnectionStateChanged", "(ZZ[B)V");
608dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
609dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_getRcFeatures = env->GetMethodID(clazz, "getRcFeatures", "([BI)V");
610dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
611dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_setplayerappsettingrsp =
612dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "setPlayerAppSettingRsp", "([BB)V");
613dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
614dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplayerappsetting =
615dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handlePlayerAppSetting", "([B[BI)V");
616dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
617dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplayerappsettingchanged =
618dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onPlayerAppSettingChanged", "([B[BI)V");
619dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
620dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleSetAbsVolume =
621dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleSetAbsVolume", "([BBB)V");
622dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
623dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleRegisterNotificationAbsVol =
624dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleRegisterNotificationAbsVol", "([BB)V");
625dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
626dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handletrackchanged =
627dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onTrackChanged", "([BB[I[Ljava/lang/String;)V");
628dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
629dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplaypositionchanged =
630dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onPlayPositionChanged", "([BII)V");
631dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
632dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplaystatuschanged =
633dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onPlayStatusChanged", "([BB)V");
634dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
635dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleGetFolderItemsRsp =
636dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleGetFolderItemsRsp",
637dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "(I[Landroid/media/browse/MediaBrowser$MediaItem;)V");
638dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleGetPlayerItemsRsp = env->GetMethodID(
639dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "handleGetPlayerItemsRsp",
640dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      "([Lcom/android/bluetooth/avrcpcontroller/AvrcpPlayer;)V");
641dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
642dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_createFromNativeMediaItem =
643dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "createFromNativeMediaItem",
644dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "([BILjava/lang/String;[I[Ljava/lang/String;)Landroid/"
645dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "media/browse/MediaBrowser$MediaItem;");
646dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_createFromNativeFolderItem = env->GetMethodID(
647dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "createFromNativeFolderItem",
648dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      "([BILjava/lang/String;I)Landroid/media/browse/MediaBrowser$MediaItem;");
649dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_createFromNativePlayerItem =
650dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "createFromNativePlayerItem",
651dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "(ILjava/lang/String;[BII)Lcom/android/bluetooth/"
652dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "avrcpcontroller/AvrcpPlayer;");
653dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleChangeFolderRsp =
654dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleChangeFolderRsp", "(I)V");
655dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleSetBrowsedPlayerRsp =
656dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleSetBrowsedPlayerRsp", "(II)V");
657dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleSetAddressedPlayerRsp =
658dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleSetAddressedPlayerRsp", "(I)V");
659dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: succeeds", __func__);
660066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
661066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
662dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void initNative(JNIEnv* env, jobject object) {
663dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass tmpMediaItem =
664dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->FindClass("android/media/browse/MediaBrowser$MediaItem");
665dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  class_MediaBrowser_MediaItem = (jclass)env->NewGlobalRef(tmpMediaItem);
666dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
667dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass tmpBtPlayer =
668dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->FindClass("com/android/bluetooth/avrcpcontroller/AvrcpPlayer");
669dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  class_AvrcpPlayer = (jclass)env->NewGlobalRef(tmpBtPlayer);
670dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
671dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const bt_interface_t* btInf = getBluetoothInterface();
672dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (btInf == NULL) {
673dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Bluetooth module is not loaded");
674dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
675dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
676dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
677dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothAvrcpInterface != NULL) {
678dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGW("Cleaning up Avrcp Interface before initializing...");
679dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface->cleanup();
680dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface = NULL;
681dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
682dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
683dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sCallbacksObj != NULL) {
684dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGW("Cleaning up Avrcp callback object");
685dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->DeleteGlobalRef(sCallbacksObj);
686dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbacksObj = NULL;
687dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
688dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
689dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothAvrcpInterface =
690dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (btrc_ctrl_interface_t*)btInf->get_profile_interface(
691dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          BT_PROFILE_AV_RC_CTRL_ID);
692dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothAvrcpInterface == NULL) {
693dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed to get Bluetooth Avrcp Controller Interface");
694dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
695dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
696dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
697dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status =
698dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sBluetoothAvrcpInterface->init(&sBluetoothAvrcpCallbacks);
699dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
700dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed to initialize Bluetooth Avrcp Controller, status: %d",
701dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          status);
702dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface = NULL;
703dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
704dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
705dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
706dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbacksObj = env->NewGlobalRef(object);
707066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
708066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
709dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void cleanupNative(JNIEnv* env, jobject object) {
710dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const bt_interface_t* btInf = getBluetoothInterface();
711dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (btInf == NULL) {
712dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Bluetooth module is not loaded");
713dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
714dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
715dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
716dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothAvrcpInterface != NULL) {
717dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface->cleanup();
718dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface = NULL;
719dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
720dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
721dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sCallbacksObj != NULL) {
722dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->DeleteGlobalRef(sCallbacksObj);
723dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbacksObj = NULL;
724dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
725066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
726066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
727dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean sendPassThroughCommandNative(JNIEnv* env, jobject object,
728dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                             jbyteArray address, jint key_code,
729dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                             jint key_state) {
730dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return JNI_FALSE;
731066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
732dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
733066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
734dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("key_code: %d, key_state: %d", key_code, key_state);
735066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
736dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
737dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
738dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
739dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
740dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
741066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
742dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->send_pass_through_cmd(
743dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)key_code, (uint8_t)key_state);
744dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
745dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending passthru command, status: %d", status);
746dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
747dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
748066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
749dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
750066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
751066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
752dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean sendGroupNavigationCommandNative(JNIEnv* env, jobject object,
753dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                 jbyteArray address,
754dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                 jint key_code,
755dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                 jint key_state) {
756dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return JNI_FALSE;
757de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
758dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
759de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
760dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("key_code: %d, key_state: %d", key_code, key_state);
761de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
762dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
763dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
764dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
765dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
766dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
767de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
768dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->send_group_navigation_cmd(
769dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)key_code, (uint8_t)key_state);
770dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
771dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending Grp Navigation command, status: %d", status);
772dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
773dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
774de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
775dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
776de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
777de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
778dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void setPlayerApplicationSettingValuesNative(JNIEnv* env, jobject object,
779dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                    jbyteArray address,
780dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                    jbyte num_attrib,
781dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                    jbyteArray attrib_ids,
782de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal                                                    jbyteArray attrib_val) {
783dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
784dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
785dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
786dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
787dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
788dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
789dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
790dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
791dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
792dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  uint8_t* pAttrs = new uint8_t[num_attrib];
793dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  uint8_t* pAttrsVal = new uint8_t[num_attrib];
794dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if ((!pAttrs) || (!pAttrsVal)) {
795dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    delete[] pAttrs;
796dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("setPlayerApplicationSettingValuesNative: not have enough memeory");
797dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
798dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
799de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
800dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* attr = env->GetByteArrayElements(attrib_ids, NULL);
801dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* attr_val = env->GetByteArrayElements(attrib_val, NULL);
802dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if ((!attr) || (!attr_val)) {
803de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    delete[] pAttrs;
804de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    delete[] pAttrsVal;
805dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
806dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
807dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
808dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
809dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int i;
810dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (i = 0; i < num_attrib; ++i) {
811dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pAttrs[i] = (uint8_t)attr[i];
812dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pAttrsVal[i] = (uint8_t)attr_val[i];
813dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
814dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
815dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_player_app_setting_cmd(
816dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)num_attrib, pAttrs, pAttrsVal);
817dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
818dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending setPlAppSettValNative command, status: %d", status);
819dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
820dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] pAttrs;
821dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] pAttrsVal;
822dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(attrib_ids, attr, 0);
823dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(attrib_val, attr_val, 0);
824dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
825de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
826de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
827dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void sendAbsVolRspNative(JNIEnv* env, jobject object, jbyteArray address,
828de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal                                jint abs_vol, jint label) {
829dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
830dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
831dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
832dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
833dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
834dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
835dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
836dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
837dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
838dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_volume_rsp(
839dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)abs_vol, (uint8_t)label);
840dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
841dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending sendAbsVolRspNative command, status: %d", status);
842dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
843dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
844de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
845de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
846dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void sendRegisterAbsVolRspNative(JNIEnv* env, jobject object,
847dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address, jbyte rsp_type,
848dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jint abs_vol, jint label) {
849dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
850dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
851dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
852dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
853dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
854dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
855dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
856dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
857dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->register_abs_vol_rsp(
858dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (btrc_notification_type_t)rsp_type, (uint8_t)abs_vol,
859dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (uint8_t)label);
860dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
861dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending sendRegisterAbsVolRspNative command, status: %d",
862dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          status);
863dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
864dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
865de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
866de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
867dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getPlaybackStateNative(JNIEnv* env, jobject object,
868dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   jbyteArray address) {
869dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
870dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
871dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
872dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
873dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
874dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
875dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
876dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
877dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status =
878dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sBluetoothAvrcpInterface->get_playback_state_cmd((bt_bdaddr_t*)addr);
879dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
880dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getPlaybackStateNative command, status: %d", status);
881dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
882dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
883ea14e69d8b1c7293869c0e4ae9180f36149a95b7Sanket Agarwal}
884ea14e69d8b1c7293869c0e4ae9180f36149a95b7Sanket Agarwal
885dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getNowPlayingListNative(JNIEnv* env, jobject object,
886dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    jbyteArray address, jbyte start,
8872df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal                                    jbyte items) {
888dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
889dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
890dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
891dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
892dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
893dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
894dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
895dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->get_now_playing_list_cmd(
896dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)start, (uint8_t)items);
897dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
898dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getNowPlayingListNative command, status: %d", status);
899dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
900dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9012df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9022df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
903dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getFolderListNative(JNIEnv* env, jobject object, jbyteArray address,
904dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                jbyte start, jbyte items) {
905dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
906dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
907dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
908dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
909dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
910dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
911dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
912dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->get_folder_list_cmd(
913dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)start, (uint8_t)items);
914dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
915dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getFolderListNative command, status: %d", status);
916dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
917dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9182df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9192df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
920dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getPlayerListNative(JNIEnv* env, jobject object, jbyteArray address,
921dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                jbyte start, jbyte items) {
922dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
923dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
924dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
925dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
926dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
927dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
928dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
929dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
930dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->get_player_list_cmd(
931dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)start, (uint8_t)items);
932dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
933dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getPlayerListNative command, status: %d", status);
934dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
935dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9362df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9372df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
938dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void changeFolderPathNative(JNIEnv* env, jobject object,
939dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   jbyteArray address, jbyte direction,
9402df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal                                   jbyteArray uidarr) {
941dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
942dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
943dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
944dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
945dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
946dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
947dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
948dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uid = env->GetByteArrayElements(uidarr, NULL);
949dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!uid) {
950dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
951dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
952dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
953dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
954dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
955dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
956dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->change_folder_path_cmd(
957dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)direction, (uint8_t*)uid);
958dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
959dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending changeFolderPathNative command, status: %d", status);
960dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
961dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9622df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9632df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
964dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void setBrowsedPlayerNative(JNIEnv* env, jobject object,
965dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   jbyteArray address, jint id) {
966dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
967dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
968dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
969dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
970dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
971dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
972dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
973dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
974dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_browsed_player_cmd(
975dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint16_t)id);
976dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
977dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending setBrowsedPlayerNative command, status: %d", status);
978dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
979dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
980a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal}
981a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
982dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void setAddressedPlayerNative(JNIEnv* env, jobject object,
983dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     jbyteArray address, jint id) {
984dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
985dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
986dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
987dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
988dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
989dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
990dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
991dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
992dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_addressed_player_cmd(
993dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint16_t)id);
994dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
995dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending setAddressedPlayerNative command, status: %d",
996dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          status);
997dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
998dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9992df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
10002df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
1001dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void playItemNative(JNIEnv* env, jobject object, jbyteArray address,
1002dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                           jbyte scope, jbyteArray uidArr, jint uidCounter) {
1003dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
1004dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1005dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
1006dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1007dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
1008dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1009dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1010dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uid = env->GetByteArrayElements(uidArr, NULL);
1011dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!uid) {
1012dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1013dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
1014dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1015dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1016dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
1017dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->play_item_cmd(
1018dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (bt_bdaddr_t*)addr, (uint8_t)scope, (uint8_t*)uid, (uint16_t)uidCounter);
1019dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
1020dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending playItemNative command, status: %d", status);
1021dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1022dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
10232df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
10242df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
1025066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic JNINativeMethod sMethods[] = {
1026dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"classInitNative", "()V", (void*)classInitNative},
1027dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"initNative", "()V", (void*)initNative},
1028dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cleanupNative", "()V", (void*)cleanupNative},
1029dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendPassThroughCommandNative", "([BII)Z",
1030dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)sendPassThroughCommandNative},
1031dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendGroupNavigationCommandNative", "([BII)Z",
1032dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)sendGroupNavigationCommandNative},
1033de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    {"setPlayerApplicationSettingValuesNative", "([BB[B[B)V",
1034dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)setPlayerApplicationSettingValuesNative},
1035dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendAbsVolRspNative", "([BII)V", (void*)sendAbsVolRspNative},
1036dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendRegisterAbsVolRspNative", "([BBII)V",
1037dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)sendRegisterAbsVolRspNative},
1038dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getPlaybackStateNative", "([B)V", (void*)getPlaybackStateNative},
1039dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getNowPlayingListNative", "([BBB)V", (void*)getNowPlayingListNative},
1040dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getFolderListNative", "([BBB)V", (void*)getFolderListNative},
1041dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getPlayerListNative", "([BBB)V", (void*)getPlayerListNative},
1042dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"changeFolderPathNative", "([BB[B)V", (void*)changeFolderPathNative},
1043dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"playItemNative", "([BB[BI)V", (void*)playItemNative},
1044dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setBrowsedPlayerNative", "([BI)V", (void*)setBrowsedPlayerNative},
1045dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setAddressedPlayerNative", "([BI)V", (void*)setAddressedPlayerNative},
1046066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood};
1047066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
1048dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenint register_com_android_bluetooth_avrcp_controller(JNIEnv* env) {
1049dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return jniRegisterNativeMethods(
1050dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env, "com/android/bluetooth/avrcpcontroller/AvrcpControllerService",
1051dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sMethods, NELEM(sMethods));
1052066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
1053066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
1054