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, &param)) != 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, &param)) != 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, &param)) != 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