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