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
56b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_passthrough_response_callback(RawAddress* 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(
63b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
642116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
652116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr for passthrough response");
662116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
672116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
68066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
69b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
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,
85b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski                                              RawAddress* 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(
91b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
922116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
932116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr for connection state");
942116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
952116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
96dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
97b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
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
104b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_get_rcfeatures_callback(RawAddress* bd_addr, int features) {
105dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
106dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
107dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
108dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1092116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
110b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
1112116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1122116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr ");
1132116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
1142116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
115dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
116b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
1172116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
118479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_getRcFeatures, addr.get(),
119dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)features);
120de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
121de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
122dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_setplayerapplicationsetting_rsp_callback(
123b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski    RawAddress* bd_addr, uint8_t accepted) {
124dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s", __func__);
125dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
126dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
127dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1282116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
129b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
1302116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1312116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr ");
1322116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
1332116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
134dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
135b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
1362116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
137dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_setplayerappsettingrsp,
138479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jint)accepted);
139de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
140de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
141dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_playerapplicationsetting_callback(
142b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski    RawAddress* bd_addr, uint8_t num_attr, btrc_player_app_attr_t* app_attrs,
143dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    uint8_t num_ext_attr, btrc_player_app_ext_attr_t* ext_attrs) {
144dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
145dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
146dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
147dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1482116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
149b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
1502116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1512116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to new jbyteArray bd addr ");
1522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
1532116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
154b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
1552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
156dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* TODO ext attrs
157dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * Flattening defined attributes: <id,num_values,values[]>
158dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
159dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jint arraylen = 0;
160dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < num_attr; i++) {
161dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    /*2 bytes for id and num */
162dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    arraylen += 2 + app_attrs[i].num_val;
163dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
164dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV(" arraylen %d", arraylen);
165dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
166479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> playerattribs(
167479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(arraylen));
168479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!playerattribs.get()) {
169dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to new jbyteArray playerattribs ");
170dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
171dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
172dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
173dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0, k = 0; (i < num_attr) && (k < arraylen); i++) {
174479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
175dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(app_attrs[i].attr_id));
176dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
177479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
178dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(app_attrs[i].num_val));
179dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
180479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k,
181479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                     app_attrs[i].num_val,
182dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)(app_attrs[i].attr_val));
183dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k = k + app_attrs[i].num_val;
184dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
185dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplayerappsetting,
186479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), playerattribs.get(), (jint)arraylen);
187de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
188de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
189dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_playerapplicationsetting_changed_callback(
190b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski    RawAddress* bd_addr, btrc_player_settings_t* p_vals) {
191dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
192dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
193dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
194dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1952116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
196b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
1972116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
1982116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
1992116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2002116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
201b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
2022116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
203dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
204dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int arraylen = p_vals->num_attr * 2;
205479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jbyteArray> playerattribs(
206479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(), sCallbackEnv->NewByteArray(arraylen));
207479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!playerattribs.get()) {
208dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Fail to new jbyteArray playerattribs ");
209dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
210dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
211dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /*
212dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * Flatening format: <id,val>
213dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
214dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0, k = 0; (i < p_vals->num_attr) && (k < arraylen); i++) {
215479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
216dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(p_vals->attr_ids[i]));
217dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
218479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetByteArrayRegion(playerattribs.get(), k, 1,
219dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     (jbyte*)&(p_vals->attr_values[i]));
220dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    k++;
221dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
222dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj,
223479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_handleplayerappsettingchanged, addr.get(),
224479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               playerattribs.get(), (jint)arraylen);
225de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
226de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
227b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_set_abs_vol_cmd_callback(RawAddress* bd_addr,
228dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                             uint8_t abs_vol, uint8_t label) {
229dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
230dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
231dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
232dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2332116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
234b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
2352116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2362116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
2372116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2382116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
239dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
240b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
2412116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
242479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetAbsVolume,
243479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)abs_vol, (jbyte)label);
244de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
245de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
246b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_register_notification_absvol_callback(RawAddress* bd_addr,
247dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                          uint8_t label) {
248dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
249dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
250dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
251dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
253b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
2542116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2552116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
2562116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2572116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
258dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
259b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
2602116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
261dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj,
262479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               method_handleRegisterNotificationAbsVol,
263479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)label);
264de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
265de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
266b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_track_changed_callback(RawAddress* bd_addr,
267dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                           uint8_t num_attr,
268dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                           btrc_element_attr_val_t* p_attrs) {
269dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /*
270dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * byteArray will be formatted like this: id,len,string
271dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * Assuming text feild to be null terminated.
272dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
273dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
274dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
275dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
276dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
2772116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
278b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
2792116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
2802116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
2812116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
2822116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
283dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
284479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jintArray> attribIds(sCallbackEnv.get(),
285479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                      sCallbackEnv->NewIntArray(num_attr));
286479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!attribIds.get()) {
287dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE(" failed to set new array for attribIds");
288dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
289dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
290b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
2912116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
292dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
293dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass strclazz = sCallbackEnv->FindClass("java/lang/String");
294479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> stringArray(
295479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv.get(),
296479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen      sCallbackEnv->NewObjectArray((jint)num_attr, strclazz, 0));
297479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!stringArray.get()) {
298dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE(" failed to get String array");
299dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
300dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
301dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
302dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (jint i = 0; i < num_attr; i++) {
303479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ScopedLocalRef<jstring> str(
304479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv.get(),
305479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->NewStringUTF((char*)(p_attrs[i].text)));
306479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    if (!str.get()) {
307dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      ALOGE("Unable to get str");
308dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      return;
309dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    }
310479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetIntArrayRegion(attribIds.get(), i, 1,
311dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    (jint*)&(p_attrs[i].attr_id));
312479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    sCallbackEnv->SetObjectArrayElement(stringArray.get(), i, str.get());
313dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
314dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
315479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handletrackchanged,
316479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)(num_attr), attribIds.get(),
317479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               stringArray.get());
318de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
319de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
320b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_play_position_changed_callback(RawAddress* bd_addr,
321dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                   uint32_t song_len,
322dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                   uint32_t song_pos) {
323dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
324dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
325dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
326dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
3272116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
328b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
3292116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3302116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
3312116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3322116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
333b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
3342116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
335dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaypositionchanged,
336479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jint)(song_len), (jint)song_pos);
337de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
338de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
339dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_play_status_changed_callback(
340b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski    RawAddress* bd_addr, btrc_play_status_t play_status) {
341dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s", __func__);
342dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
343dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
344dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
3452116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  ScopedLocalRef<jbyteArray> addr(
346b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress)));
3472116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  if (!addr.get()) {
3482116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    ALOGE("Fail to get new array ");
3492116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach    return;
3502116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach  }
351b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski  sCallbackEnv->SetByteArrayRegion(addr.get(), 0, sizeof(RawAddress),
3522116dbf94fbc00da999ac629c78627983f599a26Andre Eisenbach                                   (jbyte*)bd_addr);
353dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleplaystatuschanged,
354479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                               addr.get(), (jbyte)play_status);
355dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen}
356de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
357dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void btavrcp_get_folder_items_callback(
358b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski    RawAddress* bd_addr, btrc_status_t status,
359dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    const btrc_folder_items_t* folder_items, uint8_t count) {
360dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  /* Folder items are list of items that can be either BTRC_ITEM_PLAYER
361dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * BTRC_ITEM_MEDIA, BTRC_ITEM_FOLDER. Here we translate them to their java
362dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   * counterparts by calling the java constructor for each of the items.
363dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen   */
364dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s count %d", __func__, count);
365dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
366dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
367dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
368dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // Inspect if the first element is a folder/item or player listing. They are
369dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // always exclusive.
370dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bool isPlayerListing =
371dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      count > 0 && (folder_items[0].item_type == BTRC_ITEM_PLAYER);
372dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
373dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  // Initialize arrays for Folder OR Player listing.
374479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  ScopedLocalRef<jobjectArray> itemArray(sCallbackEnv.get(), NULL);
375dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (isPlayerListing) {
376479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    itemArray.reset(
377479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->NewObjectArray((jint)count, class_AvrcpPlayer, 0));
378dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
379479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    itemArray.reset(sCallbackEnv->NewObjectArray(
380479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        (jint)count, class_MediaBrowser_MediaItem, 0));
381479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  }
382479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen  if (!itemArray.get()) {
383479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    ALOGE("%s itemArray allocation failed.", __func__);
384479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen    return;
385dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
386dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (int i = 0; i < count; i++) {
387dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    const btrc_folder_items_t* item = &(folder_items[i]);
388dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGV("%s item type %d", __func__, item->item_type);
389dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    switch (item->item_type) {
390dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      case BTRC_ITEM_MEDIA: {
391dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse name
392479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jstring> mediaName(
393479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
394479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewStringUTF((const char*)item->media.name));
395479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!mediaName.get()) {
396479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate media name string!", __func__);
397479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
398479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
399dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse UID
400479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jbyteArray> uidByteArray(
401479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
402479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewByteArray(sizeof(uint8_t) * BTRC_UID_SIZE));
403479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!uidByteArray.get()) {
404479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate uid array!", __func__);
405479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
406479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
407479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetByteArrayRegion(uidByteArray.get(), 0,
408dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         BTRC_UID_SIZE * sizeof(uint8_t),
409dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         (jbyte*)item->media.uid);
410dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
411dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse Attrs
412479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jintArray> attrIdArray(
413479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
414479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewIntArray(item->media.num_attrs));
415479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!attrIdArray.get()) {
416479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate attr id array!", __func__);
417479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
418479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
419479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobjectArray> attrValArray(
420479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
421479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewObjectArray(
422479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                item->media.num_attrs,
423479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbackEnv->FindClass("java/lang/String"), 0));
424479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!attrValArray.get()) {
425479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate attr val array!", __func__);
426479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
427479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
428dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
429dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        for (int j = 0; j < item->media.num_attrs; j++) {
430dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          sCallbackEnv->SetIntArrayRegion(
431479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              attrIdArray.get(), j, 1,
432479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              (jint*)&(item->media.p_attrs[j].attr_id));
433479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ScopedLocalRef<jstring> attrValStr(
434479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              sCallbackEnv.get(),
435479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen              sCallbackEnv->NewStringUTF((char*)(item->media.p_attrs[j].text)));
436479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          if (!uidByteArray.get()) {
437479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            ALOGE("%s can't allocate uid array!", __func__);
438479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            return;
439479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          }
440479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          sCallbackEnv->SetObjectArrayElement(attrValArray.get(), j,
441479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                              attrValStr.get());
442dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        }
443066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
444479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobject> mediaObj(
445479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
446479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            (jobject)sCallbackEnv->CallObjectMethod(
447479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbacksObj, method_createFromNativeMediaItem,
448479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                uidByteArray.get(), (jint)item->media.type, mediaName.get(),
449479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                attrIdArray.get(), attrValArray.get()));
450479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!mediaObj.get()) {
451479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s failed to creae MediaItem for type ITEM_MEDIA", __func__);
452dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          return;
4532df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal        }
454479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetObjectArrayElement(itemArray.get(), i, mediaObj.get());
455dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        break;
456dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      }
457dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
458dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      case BTRC_ITEM_FOLDER: {
459dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse name
460479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jstring> folderName(
461479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
462479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewStringUTF((const char*)item->folder.name));
463479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!folderName.get()) {
464479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate folder name string!", __func__);
465479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
466479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
467dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse UID
468479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jbyteArray> uidByteArray(
469479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
470479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewByteArray(sizeof(uint8_t) * BTRC_UID_SIZE));
471479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!uidByteArray.get()) {
472479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate uid array!", __func__);
473479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
474479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
475479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetByteArrayRegion(uidByteArray.get(), 0,
476dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         BTRC_UID_SIZE * sizeof(uint8_t),
477dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                         (jbyte*)item->folder.uid);
478dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
479479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobject> folderObj(
480479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
481479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            (jobject)sCallbackEnv->CallObjectMethod(
482479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbacksObj, method_createFromNativeFolderItem,
483479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                uidByteArray.get(), (jint)item->folder.type, folderName.get(),
484479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                (jint)item->folder.playable));
485479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!folderObj.get()) {
486479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s failed to create MediaItem for type ITEM_FOLDER", __func__);
487dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          return;
4882df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal        }
489479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetObjectArrayElement(itemArray.get(), i,
490479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                            folderObj.get());
491dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        break;
492dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      }
493dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
494dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      case BTRC_ITEM_PLAYER: {
495dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        // Parse name
496dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        isPlayerListing = true;
497dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        jint id = (jint)item->player.player_id;
498dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        jint playerType = (jint)item->player.major_type;
499dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        jint playStatus = (jint)item->player.play_status;
500479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jbyteArray> featureBitArray(
501479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
502479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewByteArray(BTRC_FEATURE_BIT_MASK_SIZE *
503479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                       sizeof(uint8_t)));
504479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!featureBitArray.get()) {
505dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          ALOGE("%s failed to allocate featureBitArray", __func__);
506dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          return;
5072df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal        }
508dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        sCallbackEnv->SetByteArrayRegion(
509479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            featureBitArray.get(), 0,
510479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sizeof(uint8_t) * BTRC_FEATURE_BIT_MASK_SIZE,
511dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen            (jbyte*)item->player.features);
512479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jstring> playerName(
513479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
514479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv->NewStringUTF((const char*)item->player.name));
515479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!playerName.get()) {
516479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s can't allocate player name string!", __func__);
517479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
518479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
519479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        ScopedLocalRef<jobject> playerObj(
520479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            sCallbackEnv.get(),
521479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen            (jobject)sCallbackEnv->CallObjectMethod(
522479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                sCallbacksObj, method_createFromNativePlayerItem, id,
523479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                playerName.get(), featureBitArray.get(), playStatus,
524479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                playerType));
525479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        if (!playerObj.get()) {
526479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          ALOGE("%s failed to create AvrcpPlayer from ITEM_PLAYER", __func__);
527479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen          return;
528479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        }
529479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen        sCallbackEnv->SetObjectArrayElement(itemArray.get(), i,
530479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                            playerObj.get());
531dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        break;
532dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      }
533dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
534dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      default:
535dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen        ALOGE("%s cannot understand type %d", __func__, item->item_type);
5362df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    }
537dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
538dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
539dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (isPlayerListing) {
540dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGetPlayerItemsRsp,
541479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                 itemArray.get());
542dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  } else {
543dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleGetFolderItemsRsp,
544479b34835a560d032e211c3c27e10384af69c3b9Marie Janssen                                 status, itemArray.get());
545dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
5462df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
5472df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
548b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_change_path_callback(RawAddress* bd_addr, uint8_t count) {
549dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s count %d", __func__, count);
550dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
551dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
5522df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
553dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleChangeFolderRsp,
554dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)count);
5552df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
5562df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
557b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_set_browsed_player_callback(RawAddress* bd_addr,
558dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                uint8_t num_items,
559dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                uint8_t depth) {
560dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s items %d depth %d", __func__, num_items, depth);
561dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
562dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
5632df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
564dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(sCallbacksObj, method_handleSetBrowsedPlayerRsp,
565dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                               (jint)num_items, (jint)depth);
5662df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
5672df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
568b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowskistatic void btavrcp_set_addressed_player_callback(RawAddress* bd_addr,
569dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                  uint8_t status) {
570dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s status %d", __func__, status);
571a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
572dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  CallbackEnv sCallbackEnv(__func__);
573dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sCallbackEnv.valid()) return;
574a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
575dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbackEnv->CallVoidMethod(
576dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sCallbacksObj, method_handleSetAddressedPlayerRsp, (jint)status);
577a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal}
578a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
579066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic btrc_ctrl_callbacks_t sBluetoothAvrcpCallbacks = {
580066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood    sizeof(sBluetoothAvrcpCallbacks),
581066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood    btavrcp_passthrough_response_callback,
582de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_groupnavigation_response_callback,
583de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_connection_state_callback,
584de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_get_rcfeatures_callback,
585de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_setplayerapplicationsetting_rsp_callback,
586de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_playerapplicationsetting_callback,
587de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_playerapplicationsetting_changed_callback,
588de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_set_abs_vol_cmd_callback,
589de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_register_notification_absvol_callback,
590de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_track_changed_callback,
591de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    btavrcp_play_position_changed_callback,
5922df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    btavrcp_play_status_changed_callback,
5932df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    btavrcp_get_folder_items_callback,
5942df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal    btavrcp_change_path_callback,
595a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal    btavrcp_set_browsed_player_callback,
596dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    btavrcp_set_addressed_player_callback};
597066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
598066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic void classInitNative(JNIEnv* env, jclass clazz) {
599dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handlePassthroughRsp =
600dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handlePassthroughRsp", "(II[B)V");
601dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
602dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleGroupNavigationRsp =
603dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleGroupNavigationRsp", "(II)V");
604dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
605dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_onConnectionStateChanged =
606dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onConnectionStateChanged", "(ZZ[B)V");
607dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
608dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_getRcFeatures = env->GetMethodID(clazz, "getRcFeatures", "([BI)V");
609dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
610dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_setplayerappsettingrsp =
611dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "setPlayerAppSettingRsp", "([BB)V");
612dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
613dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplayerappsetting =
614dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handlePlayerAppSetting", "([B[BI)V");
615dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
616dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplayerappsettingchanged =
617dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onPlayerAppSettingChanged", "([B[BI)V");
618dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
619dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleSetAbsVolume =
620dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleSetAbsVolume", "([BBB)V");
621dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
622dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleRegisterNotificationAbsVol =
623dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleRegisterNotificationAbsVol", "([BB)V");
624dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
625dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handletrackchanged =
626dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onTrackChanged", "([BB[I[Ljava/lang/String;)V");
627dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
628dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplaypositionchanged =
629dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onPlayPositionChanged", "([BII)V");
630dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
631dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleplaystatuschanged =
632dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "onPlayStatusChanged", "([BB)V");
633dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
634dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleGetFolderItemsRsp =
635dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleGetFolderItemsRsp",
636dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "(I[Landroid/media/browse/MediaBrowser$MediaItem;)V");
637dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleGetPlayerItemsRsp = env->GetMethodID(
638dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "handleGetPlayerItemsRsp",
639dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      "([Lcom/android/bluetooth/avrcpcontroller/AvrcpPlayer;)V");
640dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
641dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_createFromNativeMediaItem =
642dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "createFromNativeMediaItem",
643dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "([BILjava/lang/String;[I[Ljava/lang/String;)Landroid/"
644dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "media/browse/MediaBrowser$MediaItem;");
645dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_createFromNativeFolderItem = env->GetMethodID(
646dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      clazz, "createFromNativeFolderItem",
647dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      "([BILjava/lang/String;I)Landroid/media/browse/MediaBrowser$MediaItem;");
648dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_createFromNativePlayerItem =
649dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "createFromNativePlayerItem",
650dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "(ILjava/lang/String;[BII)Lcom/android/bluetooth/"
651dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                       "avrcpcontroller/AvrcpPlayer;");
652dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleChangeFolderRsp =
653dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleChangeFolderRsp", "(I)V");
654dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleSetBrowsedPlayerRsp =
655dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleSetBrowsedPlayerRsp", "(II)V");
656dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  method_handleSetAddressedPlayerRsp =
657dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->GetMethodID(clazz, "handleSetAddressedPlayerRsp", "(I)V");
658dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: succeeds", __func__);
659066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
660066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
661dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void initNative(JNIEnv* env, jobject object) {
662dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass tmpMediaItem =
663dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->FindClass("android/media/browse/MediaBrowser$MediaItem");
664dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  class_MediaBrowser_MediaItem = (jclass)env->NewGlobalRef(tmpMediaItem);
665dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
666dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jclass tmpBtPlayer =
667dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env->FindClass("com/android/bluetooth/avrcpcontroller/AvrcpPlayer");
668dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  class_AvrcpPlayer = (jclass)env->NewGlobalRef(tmpBtPlayer);
669dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
670dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const bt_interface_t* btInf = getBluetoothInterface();
671dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (btInf == NULL) {
672dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Bluetooth module is not loaded");
673dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
674dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
675dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
676dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothAvrcpInterface != NULL) {
677dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGW("Cleaning up Avrcp Interface before initializing...");
678dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface->cleanup();
679dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface = NULL;
680dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
681dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
682dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sCallbacksObj != NULL) {
683dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGW("Cleaning up Avrcp callback object");
684dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->DeleteGlobalRef(sCallbacksObj);
685dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbacksObj = NULL;
686dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
687dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
688dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sBluetoothAvrcpInterface =
689dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (btrc_ctrl_interface_t*)btInf->get_profile_interface(
690dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          BT_PROFILE_AV_RC_CTRL_ID);
691dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothAvrcpInterface == NULL) {
692dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed to get Bluetooth Avrcp Controller Interface");
693dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
694dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
695dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
696dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status =
697dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sBluetoothAvrcpInterface->init(&sBluetoothAvrcpCallbacks);
698dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
699dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed to initialize Bluetooth Avrcp Controller, status: %d",
700dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          status);
701dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface = NULL;
702dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
703dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
704dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
705dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  sCallbacksObj = env->NewGlobalRef(object);
706066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
707066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
708dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void cleanupNative(JNIEnv* env, jobject object) {
709dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  const bt_interface_t* btInf = getBluetoothInterface();
710dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (btInf == NULL) {
711dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Bluetooth module is not loaded");
712dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
713dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
714dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
715dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sBluetoothAvrcpInterface != NULL) {
716dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface->cleanup();
717dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sBluetoothAvrcpInterface = NULL;
718dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
719dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
720dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (sCallbacksObj != NULL) {
721dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    env->DeleteGlobalRef(sCallbacksObj);
722dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    sCallbacksObj = NULL;
723dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
724066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
725066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
726dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean sendPassThroughCommandNative(JNIEnv* env, jobject object,
727dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                             jbyteArray address, jint key_code,
728dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                             jint key_state) {
729dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return JNI_FALSE;
730066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
731dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
732066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
733dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("key_code: %d, key_state: %d", key_code, key_state);
734066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
735dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
736dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
737dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
738dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
739dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
740066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
741dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->send_pass_through_cmd(
742b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)key_code, (uint8_t)key_state);
743dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
744dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending passthru command, status: %d", status);
745dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
746dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
747066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
748dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
749066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
750066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
751dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic jboolean sendGroupNavigationCommandNative(JNIEnv* env, jobject object,
752dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                 jbyteArray address,
753dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                 jint key_code,
754dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                 jint key_state) {
755dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return JNI_FALSE;
756de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
757dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
758de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
759dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("key_code: %d, key_state: %d", key_code, key_state);
760de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
761dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
762dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
763dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
764dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return JNI_FALSE;
765dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
766de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
767dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->send_group_navigation_cmd(
768b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)key_code, (uint8_t)key_state);
769dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
770dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending Grp Navigation command, status: %d", status);
771dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
772dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
773de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
774dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
775de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
776de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
777dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void setPlayerApplicationSettingValuesNative(JNIEnv* env, jobject object,
778dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                    jbyteArray address,
779dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                    jbyte num_attrib,
780dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                                    jbyteArray attrib_ids,
781de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal                                                    jbyteArray attrib_val) {
782dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
783dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
784dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
785dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
786dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
787dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
788dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
789dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
790dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
791dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  uint8_t* pAttrs = new uint8_t[num_attrib];
792dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  uint8_t* pAttrsVal = new uint8_t[num_attrib];
793dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if ((!pAttrs) || (!pAttrsVal)) {
794dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    delete[] pAttrs;
795dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("setPlayerApplicationSettingValuesNative: not have enough memeory");
796dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
797dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
798de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
799dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* attr = env->GetByteArrayElements(attrib_ids, NULL);
800dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* attr_val = env->GetByteArrayElements(attrib_val, NULL);
801dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if ((!attr) || (!attr_val)) {
802de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    delete[] pAttrs;
803de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    delete[] pAttrsVal;
804dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
805dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
806dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
807dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
808dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  int i;
809dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  for (i = 0; i < num_attrib; ++i) {
810dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pAttrs[i] = (uint8_t)attr[i];
811dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    pAttrsVal[i] = (uint8_t)attr_val[i];
812dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
813dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
814dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_player_app_setting_cmd(
815b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)num_attrib, pAttrs, pAttrsVal);
816dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
817dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending setPlAppSettValNative command, status: %d", status);
818dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
819dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] pAttrs;
820dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  delete[] pAttrsVal;
821dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(attrib_ids, attr, 0);
822dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(attrib_val, attr_val, 0);
823dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
824de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
825de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
826dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void sendAbsVolRspNative(JNIEnv* env, jobject object, jbyteArray address,
827de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal                                jint abs_vol, jint label) {
828dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
829dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
830dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
831dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
832dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
833dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
834dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
835dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
836dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
837dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_volume_rsp(
838b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)abs_vol, (uint8_t)label);
839dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
840dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending sendAbsVolRspNative command, status: %d", status);
841dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
842dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
843de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
844de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
845dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void sendRegisterAbsVolRspNative(JNIEnv* env, jobject object,
846dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jbyteArray address, jbyte rsp_type,
847dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                        jint abs_vol, jint label) {
848dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
849dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
850dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
851dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
852dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
853dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
854dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
855dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
856dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->register_abs_vol_rsp(
857b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (btrc_notification_type_t)rsp_type, (uint8_t)abs_vol,
858dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      (uint8_t)label);
859dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
860dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending sendRegisterAbsVolRspNative command, status: %d",
861dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          status);
862dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
863dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
864de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal}
865de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal
866dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getPlaybackStateNative(JNIEnv* env, jobject object,
867dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   jbyteArray address) {
868dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
869dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
870dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
871dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
872dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
873dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
874dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
875dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
876dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status =
877b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      sBluetoothAvrcpInterface->get_playback_state_cmd((RawAddress*)addr);
878dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
879dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getPlaybackStateNative command, status: %d", status);
880dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
881dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
882ea14e69d8b1c7293869c0e4ae9180f36149a95b7Sanket Agarwal}
883ea14e69d8b1c7293869c0e4ae9180f36149a95b7Sanket Agarwal
884dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getNowPlayingListNative(JNIEnv* env, jobject object,
885dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                    jbyteArray address, jbyte start,
8862df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal                                    jbyte items) {
887dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
888dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
889dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
890dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
891dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
892dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
893dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
894dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->get_now_playing_list_cmd(
895b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)start, (uint8_t)items);
896dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
897dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getNowPlayingListNative command, status: %d", status);
898dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
899dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9002df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9012df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
902dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getFolderListNative(JNIEnv* env, jobject object, jbyteArray address,
903dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                jbyte start, jbyte items) {
904dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
905dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
906dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
907dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
908dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
909dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
910dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGV("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
911dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->get_folder_list_cmd(
912b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)start, (uint8_t)items);
913dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
914dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getFolderListNative command, status: %d", status);
915dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
916dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9172df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9182df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
919dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void getPlayerListNative(JNIEnv* env, jobject object, jbyteArray address,
920dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                jbyte start, jbyte items) {
921dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
922dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
923dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
924dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
925dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
926dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
927dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
928dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
929dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->get_player_list_cmd(
930b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)start, (uint8_t)items);
931dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
932dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending getPlayerListNative command, status: %d", status);
933dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
934dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9352df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9362df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
937dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void changeFolderPathNative(JNIEnv* env, jobject object,
938dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   jbyteArray address, jbyte direction,
9392df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal                                   jbyteArray uidarr) {
940dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
941dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
942dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
943dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
944dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
945dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
946dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
947dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uid = env->GetByteArrayElements(uidarr, NULL);
948dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!uid) {
949dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
950dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
951dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
952dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
953dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
954dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
955dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->change_folder_path_cmd(
956b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)direction, (uint8_t*)uid);
957dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
958dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending changeFolderPathNative command, status: %d", status);
959dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
960dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9612df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9622df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
963dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void setBrowsedPlayerNative(JNIEnv* env, jobject object,
964dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                   jbyteArray address, jint id) {
965dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
966dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
967dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
968dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
969dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
970dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
971dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
972dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
973dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_browsed_player_cmd(
974b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint16_t)id);
975dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
976dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending setBrowsedPlayerNative command, status: %d", status);
977dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
978dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
979a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal}
980a7c3906cd449598a2960f9574a79edbadb96f034Sanket Agarwal
981dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void setAddressedPlayerNative(JNIEnv* env, jobject object,
982dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                                     jbyteArray address, jint id) {
983dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
984dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
985dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
986dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
987dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
988dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
989dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
990dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
991dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->set_addressed_player_cmd(
992b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint16_t)id);
993dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
994dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending setAddressedPlayerNative command, status: %d",
995dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen          status);
996dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
997dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
9982df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
9992df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
1000dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenstatic void playItemNative(JNIEnv* env, jobject object, jbyteArray address,
1001dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen                           jbyte scope, jbyteArray uidArr, jint uidCounter) {
1002dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!sBluetoothAvrcpInterface) return;
1003dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* addr = env->GetByteArrayElements(address, NULL);
1004dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!addr) {
1005dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1006dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
1007dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1008dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1009dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  jbyte* uid = env->GetByteArrayElements(uidArr, NULL);
1010dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (!uid) {
1011dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    jniThrowIOException(env, EINVAL);
1012dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    return;
1013dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1014dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen
1015dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  ALOGI("%s: sBluetoothAvrcpInterface: %p", __func__, sBluetoothAvrcpInterface);
1016dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  bt_status_t status = sBluetoothAvrcpInterface->play_item_cmd(
1017b40cec2e9a4a848b7ba724c6ed02c49604f0c669Jakub Pawlowski      (RawAddress*)addr, (uint8_t)scope, (uint8_t*)uid, (uint16_t)uidCounter);
1018dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  if (status != BT_STATUS_SUCCESS) {
1019dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    ALOGE("Failed sending playItemNative command, status: %d", status);
1020dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  }
1021dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  env->ReleaseByteArrayElements(address, addr, 0);
10222df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal}
10232df89213f063ef9d38f1531253299f80fdb0739dSanket Agarwal
1024066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodstatic JNINativeMethod sMethods[] = {
1025dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"classInitNative", "()V", (void*)classInitNative},
1026dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"initNative", "()V", (void*)initNative},
1027dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"cleanupNative", "()V", (void*)cleanupNative},
1028dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendPassThroughCommandNative", "([BII)Z",
1029dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)sendPassThroughCommandNative},
1030dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendGroupNavigationCommandNative", "([BII)Z",
1031dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)sendGroupNavigationCommandNative},
1032de00ed882cf20e5c136e349ae5e40ad35c5a74eeSanket Agarwal    {"setPlayerApplicationSettingValuesNative", "([BB[B[B)V",
1033dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)setPlayerApplicationSettingValuesNative},
1034dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendAbsVolRspNative", "([BII)V", (void*)sendAbsVolRspNative},
1035dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"sendRegisterAbsVolRspNative", "([BBII)V",
1036dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen     (void*)sendRegisterAbsVolRspNative},
1037dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getPlaybackStateNative", "([B)V", (void*)getPlaybackStateNative},
1038dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getNowPlayingListNative", "([BBB)V", (void*)getNowPlayingListNative},
1039dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getFolderListNative", "([BBB)V", (void*)getFolderListNative},
1040dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"getPlayerListNative", "([BBB)V", (void*)getPlayerListNative},
1041dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"changeFolderPathNative", "([BB[B)V", (void*)changeFolderPathNative},
1042dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"playItemNative", "([BB[BI)V", (void*)playItemNative},
1043dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setBrowsedPlayerNative", "([BI)V", (void*)setBrowsedPlayerNative},
1044dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen    {"setAddressedPlayerNative", "([BI)V", (void*)setAddressedPlayerNative},
1045066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood};
1046066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood
1047dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssenint register_com_android_bluetooth_avrcp_controller(JNIEnv* env) {
1048dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen  return jniRegisterNativeMethods(
1049dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      env, "com/android/bluetooth/avrcpcontroller/AvrcpControllerService",
1050dbd48b5fbeb449c31c92cbe8565db5e8f74c41e6Marie Janssen      sMethods, NELEM(sMethods));
1051066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
1052066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood}
1053