135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie/*
2ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Copyright (C) 2012 The Android Open Source Project
3ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
4ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License");
5ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * you may not use this file except in compliance with the License.
6ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * You may obtain a copy of the License at
7ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
8ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *      http://www.apache.org/licenses/LICENSE-2.0
9ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu *
10ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * Unless required by applicable law or agreed to in writing, software
11ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS,
12ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * See the License for the specific language governing permissions and
14ede67c26e7b2564ea35db6d9b3027a269c150e13Zhihai Xu * limitations under the License.
1535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie */
1635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
1735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#define LOG_TAG "BluetoothHidServiceJni"
1835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
1935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#define LOG_NDEBUG 0
2035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
2135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#define CHECK_CALLBACK_ENV                                                      \
2235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie   if (!checkCallbackThread()) {                                                \
23c55a9837c004044051b71bb47182ace156691283Matthew Xie       ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
2435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie       return;                                                                  \
2535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie   }
2635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
2735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#include "com_android_bluetooth.h"
2835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#include "hardware/bt_hh.h"
2935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#include "utils/Log.h"
3035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#include "android_runtime/AndroidRuntime.h"
3135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
3235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie#include <string.h>
3335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
3435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xienamespace android {
3535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
3635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic jmethodID method_onConnectStateChanged;
3757addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jmethodID method_onGetProtocolMode;
3857addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jmethodID method_onGetReport;
3957addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jmethodID method_onVirtualUnplug;
4035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
4135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic const bthh_interface_t *sBluetoothHidInterface = NULL;
4235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic jobject mCallbacksObj = NULL;
4335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic JNIEnv *sCallbackEnv = NULL;
4435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
4535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic bool checkCallbackThread() {
4689d2a16ff98d1b6254139e1589404161d5c419c7Priti Aghera
4789d2a16ff98d1b6254139e1589404161d5c419c7Priti Aghera    // Always fetch the latest callbackEnv from AdapterService.
4889d2a16ff98d1b6254139e1589404161d5c419c7Priti Aghera    // Caching this could cause this sCallbackEnv to go out-of-sync
4989d2a16ff98d1b6254139e1589404161d5c419c7Priti Aghera    // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
5089d2a16ff98d1b6254139e1589404161d5c419c7Priti Aghera    // is received
5189d2a16ff98d1b6254139e1589404161d5c419c7Priti Aghera
5289d2a16ff98d1b6254139e1589404161d5c419c7Priti Aghera    sCallbackEnv = getCallbackEnv();
5335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
5435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    JNIEnv* env = AndroidRuntime::getJNIEnv();
5535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
5635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    return true;
5735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
5835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
5935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state) {
6035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    jbyteArray addr;
6135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
6235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    CHECK_CALLBACK_ENV
6335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
6435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if (!addr) {
65c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Fail to new jbyteArray bd addr for HID channel state");
6635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
6735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        return;
6835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
6935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
7035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
7135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, addr, (jint) state);
7235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
7335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    sCallbackEnv->DeleteLocalRef(addr);
7435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
7535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
7657addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic void get_protocol_mode_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,bthh_protocol_mode_t mode) {
7757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyteArray addr;
7857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
7957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    CHECK_CALLBACK_ENV
8057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (hh_status != BTHH_OK) {
81e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("BTHH Status is not OK!");
8257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
8357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return;
8457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
8557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
8657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
8757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
88e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Fail to new jbyteArray bd addr for get protocal mode callback");
8957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
9057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return;
9157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
9257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
9357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
9457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetProtocolMode, addr, (jint) mode);
9557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
9657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->DeleteLocalRef(addr);
9757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
9857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
9957addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status) {
100e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGD("call to virtual_unplug_callback");
10157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyteArray addr;
10257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
10357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    CHECK_CALLBACK_ENV
10457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
10557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
106e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Fail to new jbyteArray bd addr for HID channel state");
10757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
10857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return;
10957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
11057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
11157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
11257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVirtualUnplug, addr, (jint) hh_status);
11357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
11457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->DeleteLocalRef(addr);
11557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
11657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    /*jbyteArray addr;
11757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jint status = hh_status;
11857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    CHECK_CALLBACK_ENV
11957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
12057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
121e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Fail to new jbyteArray bd addr for HID report");
12257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
12357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return;
12457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
12557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
12657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
12757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVirtualUnplug, addr, status);
12857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
12957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    sCallbackEnv->DeleteLocalRef(addr);*/
13057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
13157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
13257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
13335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic bthh_callbacks_t sBluetoothHidCallbacks = {
13435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    sizeof(sBluetoothHidCallbacks),
13535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    connection_state_callback,
13635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    NULL,
13757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    get_protocol_mode_callback,
13835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    NULL,
13935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    NULL,
14057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    virtual_unplug_callback
14135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie};
14235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
14335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie// Define native functions
14435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
14535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic void classInitNative(JNIEnv* env, jclass clazz) {
14635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    int err;
1476654f5c903de510a70f9e72cd5ad7837b615d93ffredc//    const bt_interface_t* btInf;
1486654f5c903de510a70f9e72cd5ad7837b615d93ffredc//    bt_status_t status;
14935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
15057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    method_onConnectStateChanged = env->GetMethodID(clazz, "onConnectStateChanged", "([BI)V");
15157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    method_onGetProtocolMode = env->GetMethodID(clazz, "onGetProtocolMode", "([BI)V");
15257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    method_onVirtualUnplug = env->GetMethodID(clazz, "onVirtualUnplug", "([BI)V");
15335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
1546654f5c903de510a70f9e72cd5ad7837b615d93ffredc/*
15535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if ( (btInf = getBluetoothInterface()) == NULL) {
156c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Bluetooth module is not loaded");
15735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        return;
15835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
15935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
16035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if ( (sBluetoothHidInterface = (bthh_interface_t *)
16135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie          btInf->get_profile_interface(BT_PROFILE_HIDHOST_ID)) == NULL) {
162c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to get Bluetooth Handsfree Interface");
16335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        return;
16435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
16535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
16635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    // TODO(BT) do this only once or
16735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    //          Do we need to do this every time the BT reenables?
16835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if ( (status = sBluetoothHidInterface->init(&sBluetoothHidCallbacks)) != BT_STATUS_SUCCESS) {
169c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed to initialize Bluetooth HID, status: %d", status);
17035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        sBluetoothHidInterface = NULL;
17135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        return;
17235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
17335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
1746654f5c903de510a70f9e72cd5ad7837b615d93ffredc*/
175c55a9837c004044051b71bb47182ace156691283Matthew Xie    ALOGI("%s: succeeds", __FUNCTION__);
17635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
17735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
1786654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void initializeNative(JNIEnv *env, jobject object) {
1796654f5c903de510a70f9e72cd5ad7837b615d93ffredc    const bt_interface_t* btInf;
1806654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
1816654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1826654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btInf = getBluetoothInterface()) == NULL) {
183e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth module is not loaded");
1846654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
1856654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1866654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1876654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sBluetoothHidInterface !=NULL) {
188e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth HID Interface before initializing...");
1896654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHidInterface->cleanup();
1906654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHidInterface = NULL;
1916654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1926654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1936654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
194e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth GID callback object");
1956654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
1966654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
1976654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
1986654f5c903de510a70f9e72cd5ad7837b615d93ffredc
1996654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2006654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (sBluetoothHidInterface = (bthh_interface_t *)
2016654f5c903de510a70f9e72cd5ad7837b615d93ffredc          btInf->get_profile_interface(BT_PROFILE_HIDHOST_ID)) == NULL) {
202e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed to get Bluetooth HID Interface");
2036654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
2046654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2056654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2066654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (status = sBluetoothHidInterface->init(&sBluetoothHidCallbacks)) != BT_STATUS_SUCCESS) {
207e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed to initialize Bluetooth HID, status: %d", status);
2086654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHidInterface = NULL;
2096654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
2106654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2116654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2126654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2136654f5c903de510a70f9e72cd5ad7837b615d93ffredc
21435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    mCallbacksObj = env->NewGlobalRef(object);
21535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
21635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
2176654f5c903de510a70f9e72cd5ad7837b615d93ffredcstatic void cleanupNative(JNIEnv *env, jobject object) {
2186654f5c903de510a70f9e72cd5ad7837b615d93ffredc    const bt_interface_t* btInf;
2196654f5c903de510a70f9e72cd5ad7837b615d93ffredc    bt_status_t status;
2206654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2216654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if ( (btInf = getBluetoothInterface()) == NULL) {
222e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth module is not loaded");
2236654f5c903de510a70f9e72cd5ad7837b615d93ffredc        return;
2246654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2256654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2266654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (sBluetoothHidInterface !=NULL) {
227e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth HID Interface...");
2286654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHidInterface->cleanup();
2296654f5c903de510a70f9e72cd5ad7837b615d93ffredc        sBluetoothHidInterface = NULL;
2306654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2316654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2326654f5c903de510a70f9e72cd5ad7837b615d93ffredc    if (mCallbacksObj != NULL) {
233e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGW("Cleaning up Bluetooth GID callback object");
2346654f5c903de510a70f9e72cd5ad7837b615d93ffredc        env->DeleteGlobalRef(mCallbacksObj);
2356654f5c903de510a70f9e72cd5ad7837b615d93ffredc        mCallbacksObj = NULL;
2366654f5c903de510a70f9e72cd5ad7837b615d93ffredc    }
2376654f5c903de510a70f9e72cd5ad7837b615d93ffredc
2386654f5c903de510a70f9e72cd5ad7837b615d93ffredc    env->DeleteGlobalRef(mCallbacksObj);
2396654f5c903de510a70f9e72cd5ad7837b615d93ffredc}
2406654f5c903de510a70f9e72cd5ad7837b615d93ffredc
24135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic jboolean connectHidNative(JNIEnv *env, jobject object, jbyteArray address) {
24235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    bt_status_t status;
24335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    jbyte *addr;
24435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    jboolean ret = JNI_TRUE;
24535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if (!sBluetoothHidInterface) return JNI_FALSE;
24635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
24735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
24835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if (!addr) {
249c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Bluetooth device address null");
25035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        return JNI_FALSE;
25135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
25235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
25335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if ((status = sBluetoothHidInterface->connect((bt_bdaddr_t *) addr)) !=
25435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie         BT_STATUS_SUCCESS) {
255c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed HID channel connection, status: %d", status);
25635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        ret = JNI_FALSE;
25735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
25835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
25935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
26035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    return ret;
26135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
26235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
26335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic jboolean disconnectHidNative(JNIEnv *env, jobject object, jbyteArray address) {
26435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    bt_status_t status;
26535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    jbyte *addr;
26635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    jboolean ret = JNI_TRUE;
26735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if (!sBluetoothHidInterface) return JNI_FALSE;
26835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
26935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    addr = env->GetByteArrayElements(address, NULL);
27035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if (!addr) {
271c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Bluetooth device address null");
27235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        return JNI_FALSE;
27335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
27435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
27535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    if ( (status = sBluetoothHidInterface->disconnect((bt_bdaddr_t *) addr)) !=
27635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie         BT_STATUS_SUCCESS) {
277c55a9837c004044051b71bb47182ace156691283Matthew Xie        ALOGE("Failed disconnect hid channel, status: %d", status);
27835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie        ret = JNI_FALSE;
27935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    }
28035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    env->ReleaseByteArrayElements(address, addr, 0);
28135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
28235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    return ret;
28335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
28435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
28557addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jboolean getProtocolModeNative(JNIEnv *env, jobject object, jbyteArray address) {
28657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bt_status_t status;
28757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyte *addr;
28857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jboolean ret = JNI_TRUE;
28957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bthh_protocol_mode_t protocolMode;
29057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!sBluetoothHidInterface) return JNI_FALSE;
29157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
29257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = env->GetByteArrayElements(address, NULL);
29357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
294e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth device address null");
29557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return JNI_FALSE;
29657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
29757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
29857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if ( (status = sBluetoothHidInterface->get_protocol((bt_bdaddr_t *) addr, (bthh_protocol_mode_t) protocolMode)) !=
29957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera         BT_STATUS_SUCCESS) {
300e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed get protocol mode, status: %d", status);
30157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        ret = JNI_FALSE;
30257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
30357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseByteArrayElements(address, addr, 0);
30457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
30557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    return ret;
30657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
30757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
30857addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jboolean virtualUnPlugNative(JNIEnv *env, jobject object, jbyteArray address) {
30957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bt_status_t status;
31057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyte *addr;
31157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jboolean ret = JNI_TRUE;
31257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!sBluetoothHidInterface) return JNI_FALSE;
31357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
31457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = env->GetByteArrayElements(address, NULL);
31557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        if (!addr) {
316e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie            ALOGE("Bluetooth device address null");
31757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera            return JNI_FALSE;
31857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        }
31957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if ( (status = sBluetoothHidInterface->virtual_unplug((bt_bdaddr_t *) addr)) !=
32057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera             BT_STATUS_SUCCESS) {
321e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed virual unplug, status: %d", status);
32257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        ret = JNI_FALSE;
32357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
32457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseByteArrayElements(address, addr, 0);
32557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    return ret;
32657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
32757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
32857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
32957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
33057addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jboolean setProtocolModeNative(JNIEnv *env, jobject object, jbyteArray address, jint protocolMode) {
33157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bt_status_t status;
33257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyte *addr;
33357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jboolean ret = JNI_TRUE;
33457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!sBluetoothHidInterface) return JNI_FALSE;
33557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
336e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGD("%s: protocolMode = %d", __FUNCTION__, protocolMode);
33757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
33857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = env->GetByteArrayElements(address, NULL);
33957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
340e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth device address null");
34157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return JNI_FALSE;
34257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
34357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
34457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bthh_protocol_mode_t mode;
34557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    switch(protocolMode){
34657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        case 0:
34757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera            mode = BTHH_REPORT_MODE;
34857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera            break;
34957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        case 1:
35057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera            mode = BTHH_BOOT_MODE;
35157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera            break;
35257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        default:
353e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie            ALOGE("Unknown HID protocol mode");
35457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera            return JNI_FALSE;
35557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
35657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if ( (status = sBluetoothHidInterface->set_protocol((bt_bdaddr_t *) addr, mode)) !=
35757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera             BT_STATUS_SUCCESS) {
358e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed set protocol mode, status: %d", status);
35957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        ret = JNI_FALSE;
36057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
36157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseByteArrayElements(address, addr, 0);
36257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
36357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    return JNI_TRUE;
36457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
36557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
36657addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jboolean getReportNative(JNIEnv *env, jobject object, jbyteArray address, jbyte reportType, jbyte reportId, jint bufferSize) {
367e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGD("%s: reportType = %d, reportId = %d, bufferSize = %d", __FUNCTION__, reportType, reportId, bufferSize);
36857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
36957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bt_status_t status;
37057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyte *addr;
37157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jboolean ret = JNI_TRUE;
37257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!sBluetoothHidInterface) return JNI_FALSE;
37357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
37457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = env->GetByteArrayElements(address, NULL);
37557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
376e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth device address null");
37757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return JNI_FALSE;
37857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
37957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
38057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jint rType = reportType;
38157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jint rId = reportId;
38257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
38357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if ( (status = sBluetoothHidInterface->get_report((bt_bdaddr_t *) addr, (bthh_report_type_t) rType, (uint8_t) rId, bufferSize)) !=
38457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera             BT_STATUS_SUCCESS) {
385e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed get report, status: %d", status);
38657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        ret = JNI_FALSE;
38757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
38857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseByteArrayElements(address, addr, 0);
38957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
39057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    return ret;
39157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
39257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
39357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
39457addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jboolean setReportNative(JNIEnv *env, jobject object, jbyteArray address, jbyte reportType, jstring report) {
395e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGD("%s: reportType = %d", __FUNCTION__, reportType);
39657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bt_status_t status;
39757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyte *addr;
39857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jboolean ret = JNI_TRUE;
39957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!sBluetoothHidInterface) return JNI_FALSE;
40057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
40157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = env->GetByteArrayElements(address, NULL);
40257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
403e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth device address null");
40457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return JNI_FALSE;
40557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
40657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jint rType = reportType;
40757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    const char *c_report = env->GetStringUTFChars(report, NULL);
40857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
40957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if ( (status = sBluetoothHidInterface->set_report((bt_bdaddr_t *) addr, (bthh_report_type_t)rType, (char*) c_report)) !=
41057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera             BT_STATUS_SUCCESS) {
411e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed set report, status: %d", status);
41257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        ret = JNI_FALSE;
41357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
41457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseStringUTFChars(report, c_report);
41557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseByteArrayElements(address, addr, 0);
41657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
41757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    return ret;
41857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
41957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
42057addccaa75691f8eb6f35204d608a63695a9705Priti Agherastatic jboolean sendDataNative(JNIEnv *env, jobject object, jbyteArray address, jstring report) {
421e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie    ALOGD("%s", __FUNCTION__);
42257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    bt_status_t status;
42357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jbyte *addr;
42457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    jboolean ret = JNI_TRUE;
42557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!sBluetoothHidInterface) return JNI_FALSE;
42657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
42757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    addr = env->GetByteArrayElements(address, NULL);
42857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if (!addr) {
429e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Bluetooth device address null");
43057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        return JNI_FALSE;
43157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
43257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    const char *c_report = env->GetStringUTFChars(report, NULL);
43357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    if ( (status = sBluetoothHidInterface->send_data((bt_bdaddr_t *) addr, (char*) c_report)) !=
43457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera             BT_STATUS_SUCCESS) {
435e469f16e5a7d99471d7db1b216d422e8d12cc4cfMatthew Xie        ALOGE("Failed set report, status: %d", status);
43657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera        ret = JNI_FALSE;
43757addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    }
43857addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseStringUTFChars(report, c_report);
43957addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    env->ReleaseByteArrayElements(address, addr, 0);
44057addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
44157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    return ret;
44257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
44357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera}
44457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera
44535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xiestatic JNINativeMethod sMethods[] = {
44635207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    {"classInitNative", "()V", (void *) classInitNative},
4476654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"initializeNative", "()V", (void *) initializeNative},
4486654f5c903de510a70f9e72cd5ad7837b615d93ffredc    {"cleanupNative", "()V", (void *) cleanupNative},
44935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    {"connectHidNative", "([B)Z", (void *) connectHidNative},
45035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    {"disconnectHidNative", "([B)Z", (void *) disconnectHidNative},
45157addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    {"getProtocolModeNative", "([B)Z", (void *) getProtocolModeNative},
45257addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    {"virtualUnPlugNative", "([B)Z", (void *) virtualUnPlugNative},
45357addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    {"setProtocolModeNative", "([BB)Z", (void *) setProtocolModeNative},
45457addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    {"getReportNative", "([BBBI)Z", (void *) getReportNative},
45557addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    {"setReportNative", "([BBLjava/lang/String;)Z", (void *) setReportNative},
45657addccaa75691f8eb6f35204d608a63695a9705Priti Aghera    {"sendDataNative", "([BLjava/lang/String;)Z", (void *) sendDataNative},
45735207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie};
45835207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
45935207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xieint register_com_android_bluetooth_hid(JNIEnv* env)
46035207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie{
46135207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie    return jniRegisterNativeMethods(env, "com/android/bluetooth/hid/HidService",
46235207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie                                    sMethods, NELEM(sMethods));
46335207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
46435207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie
46535207a5638f61caca5b9abb31e5c6850a9478a52Matthew Xie}
466