1c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu/* 2c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Copyright (C) 2012 The Android Open Source Project 3c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 4c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * you may not use this file except in compliance with the License. 6c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * You may obtain a copy of the License at 7c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 8c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 10c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * See the License for the specific language governing permissions and 14c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * limitations under the License. 15c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu */ 16c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 17c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#define LOG_TAG "BluetoothAvrcpServiceJni" 18c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 19c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#define LOG_NDEBUG 0 20c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 21c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "com_android_bluetooth.h" 22c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "hardware/bt_rc.h" 23c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "utils/Log.h" 24c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include "android_runtime/AndroidRuntime.h" 25c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 26c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu#include <string.h> 27c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 28c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xunamespace android { 2917675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic jmethodID method_getRcFeatures; 30c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jmethodID method_getPlayStatus; 31c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jmethodID method_getElementAttr; 32c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jmethodID method_registerNotification; 3317675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic jmethodID method_volumeChangeCallback; 34ace834feb02adabd61f628c4471147aea02d939cJohn Dustatic jmethodID method_handlePassthroughCmd; 35c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 36c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic const btrc_interface_t *sBluetoothAvrcpInterface = NULL; 37c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jobject mCallbacksObj = NULL; 38c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic JNIEnv *sCallbackEnv = NULL; 39c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 40c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic bool checkCallbackThread() { 41c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // Always fetch the latest callbackEnv from AdapterService. 42c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // Caching this could cause this sCallbackEnv to go out-of-sync 43c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event 44c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu // is received 45c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv = getCallbackEnv(); 46c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 47c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu JNIEnv* env = AndroidRuntime::getJNIEnv(); 48c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (sCallbackEnv != env || sCallbackEnv == NULL) return false; 49c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return true; 50c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 51c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 5217675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic void btavrcp_remote_features_callback(bt_bdaddr_t* bd_addr, btrc_remote_features_t features) { 5317675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s", __FUNCTION__); 5417675906064bb72fdcca75baa56cdf8bb8968d01John Du jbyteArray addr; 5517675906064bb72fdcca75baa56cdf8bb8968d01John Du 5617675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!checkCallbackThread()) { 5717675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 5817675906064bb72fdcca75baa56cdf8bb8968d01John Du return; 5917675906064bb72fdcca75baa56cdf8bb8968d01John Du } 6017675906064bb72fdcca75baa56cdf8bb8968d01John Du addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); 6117675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!addr) { 62f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora ALOGE("Unable to allocate byte array for bd_addr"); 6317675906064bb72fdcca75baa56cdf8bb8968d01John Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 6417675906064bb72fdcca75baa56cdf8bb8968d01John Du return; 6517675906064bb72fdcca75baa56cdf8bb8968d01John Du } 6617675906064bb72fdcca75baa56cdf8bb8968d01John Du 67f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora if (mCallbacksObj) { 68f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*) bd_addr); 69f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getRcFeatures, addr, (jint)features); 70f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } else { 71f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora ALOGE("%s: mCallbacksObj is null", __FUNCTION__); 72f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 73f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora 7417675906064bb72fdcca75baa56cdf8bb8968d01John Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 75bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde /* TODO: I think we leak the addr object, we should add a 76bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * sCallbackEnv->DeleteLocalRef(addr) */ 7717675906064bb72fdcca75baa56cdf8bb8968d01John Du} 7817675906064bb72fdcca75baa56cdf8bb8968d01John Du 79c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void btavrcp_get_play_status_callback() { 80c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s", __FUNCTION__); 81c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 82c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!checkCallbackThread()) { 83c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 84c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 85c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 86c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 87f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora if (mCallbacksObj) { 88f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getPlayStatus); 89f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } else { 90f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora ALOGE("%s: mCallbacksObj is null", __FUNCTION__); 91f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 92c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 93c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 94c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 95c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void btavrcp_get_element_attr_callback(uint8_t num_attr, btrc_media_attr_t *p_attrs) { 96c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jintArray attrs; 97c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 98c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s", __FUNCTION__); 99c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 100c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!checkCallbackThread()) { 101c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 102c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 103c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 104c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu attrs = (jintArray)sCallbackEnv->NewIntArray(num_attr); 105c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!attrs) { 106c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Fail to new jintArray for attrs"); 107c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 108c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 109c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 110c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv->SetIntArrayRegion(attrs, 0, num_attr, (jint *)p_attrs); 111f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora if (mCallbacksObj) { 112f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora sCallbackEnv->CallVoidMethod(mCallbacksObj, method_getElementAttr, (jbyte)num_attr, attrs); 113f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } else { 114f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora ALOGE("%s: mCallbacksObj is null", __FUNCTION__); 115f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 116c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 117c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sCallbackEnv->DeleteLocalRef(attrs); 118c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 119c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 120c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void btavrcp_register_notification_callback(btrc_event_id_t event_id, uint32_t param) { 121c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!checkCallbackThread()) { 122c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 123c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 124c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 125f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora if (mCallbacksObj) { 126f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora sCallbackEnv->CallVoidMethod(mCallbacksObj, method_registerNotification, 127c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (jint)event_id, (jint)param); 128f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } else { 129f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora ALOGE("%s: mCallbacksObj is null", __FUNCTION__); 130f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 131c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 132c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 133c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 13417675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic void btavrcp_volume_change_callback(uint8_t volume, uint8_t ctype) { 13517675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s", __FUNCTION__); 13617675906064bb72fdcca75baa56cdf8bb8968d01John Du 13717675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!checkCallbackThread()) { 13817675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 13917675906064bb72fdcca75baa56cdf8bb8968d01John Du return; 14017675906064bb72fdcca75baa56cdf8bb8968d01John Du } 141f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora if (mCallbacksObj) { 142f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora sCallbackEnv->CallVoidMethod(mCallbacksObj, method_volumeChangeCallback, (jint)volume, 143f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora (jint)ctype); 144f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } else { 145f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora ALOGE("%s: mCallbacksObj is null", __FUNCTION__); 146f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 14717675906064bb72fdcca75baa56cdf8bb8968d01John Du 14817675906064bb72fdcca75baa56cdf8bb8968d01John Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 14917675906064bb72fdcca75baa56cdf8bb8968d01John Du} 15017675906064bb72fdcca75baa56cdf8bb8968d01John Du 151ace834feb02adabd61f628c4471147aea02d939cJohn Dustatic void btavrcp_passthrough_command_callback(int id, int pressed) { 152ace834feb02adabd61f628c4471147aea02d939cJohn Du ALOGI("%s", __FUNCTION__); 153ace834feb02adabd61f628c4471147aea02d939cJohn Du 154ace834feb02adabd61f628c4471147aea02d939cJohn Du if (!checkCallbackThread()) { 155ace834feb02adabd61f628c4471147aea02d939cJohn Du ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); 156ace834feb02adabd61f628c4471147aea02d939cJohn Du return; 157ace834feb02adabd61f628c4471147aea02d939cJohn Du } 158f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora if (mCallbacksObj) { 159f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora sCallbackEnv->CallVoidMethod(mCallbacksObj, method_handlePassthroughCmd, 160f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora (jint)id, (jint)pressed); 161f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } else { 162f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora ALOGE("%s: mCallbacksObj is null", __FUNCTION__); 163f19f1ac64a5fefb248ab15b918d009b926c99ddeNitin Arora } 164ace834feb02adabd61f628c4471147aea02d939cJohn Du checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__); 165ace834feb02adabd61f628c4471147aea02d939cJohn Du} 166ace834feb02adabd61f628c4471147aea02d939cJohn Du 167c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic btrc_callbacks_t sBluetoothAvrcpCallbacks = { 168c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sizeof(sBluetoothAvrcpCallbacks), 16917675906064bb72fdcca75baa56cdf8bb8968d01John Du btavrcp_remote_features_callback, 170c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btavrcp_get_play_status_callback, 171c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 172c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 173c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 174c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 175c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 176c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu NULL, 177c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btavrcp_get_element_attr_callback, 178ace834feb02adabd61f628c4471147aea02d939cJohn Du btavrcp_register_notification_callback, 17917675906064bb72fdcca75baa56cdf8bb8968d01John Du btavrcp_volume_change_callback, 1805c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta btavrcp_passthrough_command_callback, 181c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu}; 182c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 183c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void classInitNative(JNIEnv* env, jclass clazz) { 18417675906064bb72fdcca75baa56cdf8bb8968d01John Du method_getRcFeatures = 18517675906064bb72fdcca75baa56cdf8bb8968d01John Du env->GetMethodID(clazz, "getRcFeatures", "([BI)V"); 186c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu method_getPlayStatus = 187c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->GetMethodID(clazz, "getPlayStatus", "()V"); 188c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 189c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu method_getElementAttr = 190c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->GetMethodID(clazz, "getElementAttr", "(B[I)V"); 191c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 192c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu method_registerNotification = 193c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->GetMethodID(clazz, "registerNotification", "(II)V"); 194c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 19517675906064bb72fdcca75baa56cdf8bb8968d01John Du method_volumeChangeCallback = 19617675906064bb72fdcca75baa56cdf8bb8968d01John Du env->GetMethodID(clazz, "volumeChangeCallback", "(II)V"); 19717675906064bb72fdcca75baa56cdf8bb8968d01John Du 198ace834feb02adabd61f628c4471147aea02d939cJohn Du method_handlePassthroughCmd = 199ace834feb02adabd61f628c4471147aea02d939cJohn Du env->GetMethodID(clazz, "handlePassthroughCmd", "(II)V"); 200ace834feb02adabd61f628c4471147aea02d939cJohn Du 201c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: succeeds", __FUNCTION__); 202c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 203c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 204c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void initNative(JNIEnv *env, jobject object) { 205c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu const bt_interface_t* btInf; 206c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 207c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 208c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (btInf = getBluetoothInterface()) == NULL) { 209c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Bluetooth module is not loaded"); 210c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 211c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 212c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 213c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (sBluetoothAvrcpInterface !=NULL) { 214c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGW("Cleaning up Avrcp Interface before initializing..."); 215c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface->cleanup(); 216c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface = NULL; 217c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 218c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 219c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (mCallbacksObj != NULL) { 220c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGW("Cleaning up Avrcp callback object"); 221c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteGlobalRef(mCallbacksObj); 222c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mCallbacksObj = NULL; 223c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 224c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 225c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (sBluetoothAvrcpInterface = (btrc_interface_t *) 226c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btInf->get_profile_interface(BT_PROFILE_AV_RC_ID)) == NULL) { 227c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed to get Bluetooth Avrcp Interface"); 228c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 229c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 230c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 231c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (status = sBluetoothAvrcpInterface->init(&sBluetoothAvrcpCallbacks)) != 232c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu BT_STATUS_SUCCESS) { 233c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed to initialize Bluetooth Avrcp, status: %d", status); 234c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface = NULL; 235c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 236c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 237c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 238c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mCallbacksObj = env->NewGlobalRef(object); 239c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 240c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 241c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic void cleanupNative(JNIEnv *env, jobject object) { 242c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu const bt_interface_t* btInf; 243c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 244c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ( (btInf = getBluetoothInterface()) == NULL) { 245c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Bluetooth module is not loaded"); 246c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return; 247c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 248c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 249c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (sBluetoothAvrcpInterface !=NULL) { 250c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface->cleanup(); 251c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sBluetoothAvrcpInterface = NULL; 252c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 253c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 254c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (mCallbacksObj != NULL) { 255c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteGlobalRef(mCallbacksObj); 256c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mCallbacksObj = NULL; 257c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 258c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 259c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 260c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jboolean getPlayStatusRspNative(JNIEnv *env, jobject object, jint playStatus, 261c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint songLen, jint songPos) { 262c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 263c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 264c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 265c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 266c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 267c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->get_play_status_rsp((btrc_play_status_t)playStatus, 268c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu songLen, songPos)) != BT_STATUS_SUCCESS) { 269c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed get_play_status_rsp, status: %d", status); 270c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 271c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 272c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 273c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 274c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 275c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu static jboolean getElementAttrRspNative(JNIEnv *env, jobject object, jbyte numAttr, 276c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jintArray attrIds, jobjectArray textArray) { 277c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint *attr; 278c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 279c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jstring text; 280c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu int i; 281c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btrc_element_attr_val_t *pAttrs = NULL; 282c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu const char* textStr; 283c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 284c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 285c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 286c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (numAttr > BTRC_MAX_ELEM_ATTR_SIZE) { 287c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: number of attributes exceed maximum"); 288c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 289c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 290c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 291c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu pAttrs = new btrc_element_attr_val_t[numAttr]; 292c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!pAttrs) { 293c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: not have enough memeory"); 294c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 295c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 296c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 297c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu attr = env->GetIntArrayElements(attrIds, NULL); 298c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!attr) { 299c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu delete[] pAttrs; 300c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jniThrowIOException(env, EINVAL); 301c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 302c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 303c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 304c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu for (i = 0; i < numAttr; ++i) { 305c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu text = (jstring) env->GetObjectArrayElement(textArray, i); 306c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu textStr = env->GetStringUTFChars(text, NULL); 307c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!textStr) { 308c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: GetStringUTFChars return NULL"); 309c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteLocalRef(text); 310c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu break; 311c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 312885213461ae72d6db178c95fafc01cde153230dbZhihai Xu 313885213461ae72d6db178c95fafc01cde153230dbZhihai Xu pAttrs[i].attr_id = attr[i]; 314c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (strlen(textStr) >= BTRC_MAX_ATTR_STR_LEN) { 315c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("get_element_attr_rsp: string length exceed maximum"); 316885213461ae72d6db178c95fafc01cde153230dbZhihai Xu strncpy((char *)pAttrs[i].text, textStr, BTRC_MAX_ATTR_STR_LEN-1); 317885213461ae72d6db178c95fafc01cde153230dbZhihai Xu pAttrs[i].text[BTRC_MAX_ATTR_STR_LEN-1] = 0; 318885213461ae72d6db178c95fafc01cde153230dbZhihai Xu } else { 319885213461ae72d6db178c95fafc01cde153230dbZhihai Xu strcpy((char *)pAttrs[i].text, textStr); 320c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 321c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseStringUTFChars(text, textStr); 322c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->DeleteLocalRef(text); 323c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 324c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 325c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (i < numAttr) { 326c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu delete[] pAttrs; 327c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseIntArrayElements(attrIds, attr, 0); 328c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 329c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 330c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 331c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->get_element_attr_rsp(numAttr, pAttrs)) != 332c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu BT_STATUS_SUCCESS) { 333c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed get_element_attr_rsp, status: %d", status); 334c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 335c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 336c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu delete[] pAttrs; 337c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseIntArrayElements(attrIds, attr, 0); 338c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 339c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 340c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 341c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jboolean registerNotificationRspPlayStatusNative(JNIEnv *env, jobject object, 342c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint type, jint playStatus) { 343c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 344c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btrc_register_notification_t param; 345c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 346c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 347c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 348c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 349c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu param.play_status = (btrc_play_status_t)playStatus; 350c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->register_notification_rsp(BTRC_EVT_PLAY_STATUS_CHANGED, 351c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (btrc_notification_type_t)type, ¶m)) != BT_STATUS_SUCCESS) { 352c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed register_notification_rsp play status, status: %d", status); 353c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 354c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 355c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 356c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 357c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 358c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic jboolean registerNotificationRspTrackChangeNative(JNIEnv *env, jobject object, 359c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jint type, jbyteArray track) { 360c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu bt_status_t status; 361c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu btrc_register_notification_t param; 362c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jbyte *trk; 363c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu int i; 364c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 365c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 366c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 367c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 368c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu trk = env->GetByteArrayElements(track, NULL); 369c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (!trk) { 370c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu jniThrowIOException(env, EINVAL); 371c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return JNI_FALSE; 372c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 373c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 374c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu for (i = 0; i < BTRC_UID_SIZE; ++i) { 375c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu param.track[i] = trk[i]; 376c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 377c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 378c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if ((status = sBluetoothAvrcpInterface->register_notification_rsp(BTRC_EVT_TRACK_CHANGE, 379c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (btrc_notification_type_t)type, ¶m)) != BT_STATUS_SUCCESS) { 380c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ALOGE("Failed register_notification_rsp track change, status: %d", status); 381c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 382c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 383c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu env->ReleaseByteArrayElements(track, trk, 0); 384c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 385c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 386c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 387aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xustatic jboolean registerNotificationRspPlayPosNative(JNIEnv *env, jobject object, 388aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu jint type, jint playPos) { 389aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu bt_status_t status; 390aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu btrc_register_notification_t param; 391aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 392aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu if (!sBluetoothAvrcpInterface) return JNI_FALSE; 393aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 394aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu param.song_pos = (uint32_t)playPos; 395aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu if ((status = sBluetoothAvrcpInterface->register_notification_rsp(BTRC_EVT_PLAY_POS_CHANGED, 396aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu (btrc_notification_type_t)type, ¶m)) != BT_STATUS_SUCCESS) { 397aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu ALOGE("Failed register_notification_rsp play position, status: %d", status); 398aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu } 399aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 400aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 401aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu} 402aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 40317675906064bb72fdcca75baa56cdf8bb8968d01John Dustatic jboolean setVolumeNative(JNIEnv *env, jobject object, jint volume) { 40417675906064bb72fdcca75baa56cdf8bb8968d01John Du bt_status_t status; 40517675906064bb72fdcca75baa56cdf8bb8968d01John Du 40617675906064bb72fdcca75baa56cdf8bb8968d01John Du //TODO: delete test code 40717675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s: jint: %d, uint8_t: %u", __FUNCTION__, volume, (uint8_t) volume); 40817675906064bb72fdcca75baa56cdf8bb8968d01John Du 40917675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGI("%s: sBluetoothAvrcpInterface: %p", __FUNCTION__, sBluetoothAvrcpInterface); 41017675906064bb72fdcca75baa56cdf8bb8968d01John Du if (!sBluetoothAvrcpInterface) return JNI_FALSE; 41117675906064bb72fdcca75baa56cdf8bb8968d01John Du 41217675906064bb72fdcca75baa56cdf8bb8968d01John Du if ((status = sBluetoothAvrcpInterface->set_volume((uint8_t)volume)) != BT_STATUS_SUCCESS) { 41317675906064bb72fdcca75baa56cdf8bb8968d01John Du ALOGE("Failed set_volume, status: %d", status); 41417675906064bb72fdcca75baa56cdf8bb8968d01John Du } 41517675906064bb72fdcca75baa56cdf8bb8968d01John Du 41617675906064bb72fdcca75baa56cdf8bb8968d01John Du return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; 41717675906064bb72fdcca75baa56cdf8bb8968d01John Du} 41817675906064bb72fdcca75baa56cdf8bb8968d01John Du 419c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xustatic JNINativeMethod sMethods[] = { 420c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"classInitNative", "()V", (void *) classInitNative}, 421c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"initNative", "()V", (void *) initNative}, 422c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"cleanupNative", "()V", (void *) cleanupNative}, 423c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"getPlayStatusRspNative", "(III)Z", (void *) getPlayStatusRspNative}, 424c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"getElementAttrRspNative", "(B[I[Ljava/lang/String;)Z", (void *) getElementAttrRspNative}, 425c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"registerNotificationRspPlayStatusNative", "(II)Z", 426c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (void *) registerNotificationRspPlayStatusNative}, 427c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu {"registerNotificationRspTrackChangeNative", "(I[B)Z", 428c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu (void *) registerNotificationRspTrackChangeNative}, 429aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu {"registerNotificationRspPlayPosNative", "(II)Z", 430aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu (void *) registerNotificationRspPlayPosNative}, 43117675906064bb72fdcca75baa56cdf8bb8968d01John Du {"setVolumeNative", "(I)Z", 4325c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta (void *) setVolumeNative}, 433c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu}; 434c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 435c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuint register_com_android_bluetooth_avrcp(JNIEnv* env) 436c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu{ 437066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood return jniRegisterNativeMethods(env, "com/android/bluetooth/avrcp/Avrcp", 438c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu sMethods, NELEM(sMethods)); 439c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 440c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 441c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 442