blob: 684af233fd5bccb6dc0a174d7bb1ff9107f0670c [file] [log] [blame]
Matthew Xie35207a52012-03-21 23:11:40 -07001/*
Zhihai Xuede67c22012-10-23 17:01:01 -07002 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Matthew Xie35207a52012-03-21 23:11:40 -070015 */
16
17#define LOG_TAG "BluetoothHidServiceJni"
18
19#define LOG_NDEBUG 0
20
21#define CHECK_CALLBACK_ENV \
22 if (!checkCallbackThread()) { \
Matthew Xiec55a9832012-04-07 03:44:13 -070023 ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);\
Matthew Xie35207a52012-03-21 23:11:40 -070024 return; \
25 }
26
27#include "com_android_bluetooth.h"
28#include "hardware/bt_hh.h"
29#include "utils/Log.h"
30#include "android_runtime/AndroidRuntime.h"
31
32#include <string.h>
33
34namespace android {
35
36static jmethodID method_onConnectStateChanged;
Priti Aghera57addcc2012-04-09 12:59:30 -070037static jmethodID method_onGetProtocolMode;
38static jmethodID method_onGetReport;
broodplank0c589302013-12-29 05:41:41 +010039static jmethodID method_onGetIdleTime;
Priti Aghera57addcc2012-04-09 12:59:30 -070040static jmethodID method_onVirtualUnplug;
Matthew Xie35207a52012-03-21 23:11:40 -070041
42static const bthh_interface_t *sBluetoothHidInterface = NULL;
43static jobject mCallbacksObj = NULL;
44static JNIEnv *sCallbackEnv = NULL;
45
46static bool checkCallbackThread() {
Priti Aghera89d2a162012-04-04 12:32:12 -070047
48 // Always fetch the latest callbackEnv from AdapterService.
49 // Caching this could cause this sCallbackEnv to go out-of-sync
50 // with the AdapterService's ENV if an ASSOCIATE/DISASSOCIATE event
51 // is received
52
53 sCallbackEnv = getCallbackEnv();
Matthew Xie35207a52012-03-21 23:11:40 -070054
55 JNIEnv* env = AndroidRuntime::getJNIEnv();
56 if (sCallbackEnv != env || sCallbackEnv == NULL) return false;
57 return true;
58}
59
60static void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state) {
61 jbyteArray addr;
62
63 CHECK_CALLBACK_ENV
64 addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
65 if (!addr) {
Matthew Xiec55a9832012-04-07 03:44:13 -070066 ALOGE("Fail to new jbyteArray bd addr for HID channel state");
Matthew Xie35207a52012-03-21 23:11:40 -070067 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
68 return;
69 }
70 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
71
72 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectStateChanged, addr, (jint) state);
73 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
74 sCallbackEnv->DeleteLocalRef(addr);
75}
76
Priti Aghera57addcc2012-04-09 12:59:30 -070077static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,bthh_protocol_mode_t mode) {
78 jbyteArray addr;
79
80 CHECK_CALLBACK_ENV
81 if (hh_status != BTHH_OK) {
Matthew Xiee469f162012-06-05 23:57:59 -070082 ALOGE("BTHH Status is not OK!");
Priti Aghera57addcc2012-04-09 12:59:30 -070083 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
84 return;
85 }
86
87 addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
88 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -070089 ALOGE("Fail to new jbyteArray bd addr for get protocal mode callback");
Priti Aghera57addcc2012-04-09 12:59:30 -070090 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
91 return;
92 }
93 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
94
95 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetProtocolMode, addr, (jint) mode);
96 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
97 sCallbackEnv->DeleteLocalRef(addr);
98}
99
broodplank0c589302013-12-29 05:41:41 +0100100static void get_idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_time) {
101 jbyteArray addr;
102
103 CHECK_CALLBACK_ENV
104 if (hh_status != BTHH_OK) {
105 ALOGE("BTHH Status is not OK!");
106 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
107 return;
108 }
109
110 addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
111 if (!addr) {
112 ALOGE("Fail to new jbyteArray bd addr for get protocal mode callback");
113 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
114 return;
115 }
116 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
117
118 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetIdleTime, addr, (jint) idle_time);
119 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
120 sCallbackEnv->DeleteLocalRef(addr);
121}
122
Priti Aghera57addcc2012-04-09 12:59:30 -0700123static void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status) {
Matthew Xiee469f162012-06-05 23:57:59 -0700124 ALOGD("call to virtual_unplug_callback");
Priti Aghera57addcc2012-04-09 12:59:30 -0700125 jbyteArray addr;
126
127 CHECK_CALLBACK_ENV
128 addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
129 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700130 ALOGE("Fail to new jbyteArray bd addr for HID channel state");
Priti Aghera57addcc2012-04-09 12:59:30 -0700131 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
132 return;
133 }
134 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
135
136 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVirtualUnplug, addr, (jint) hh_status);
137 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
138 sCallbackEnv->DeleteLocalRef(addr);
139
140 /*jbyteArray addr;
141 jint status = hh_status;
142 CHECK_CALLBACK_ENV
143 addr = sCallbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
144 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700145 ALOGE("Fail to new jbyteArray bd addr for HID report");
Priti Aghera57addcc2012-04-09 12:59:30 -0700146 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
147 return;
148 }
149 sCallbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *) bd_addr);
150
151 sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onVirtualUnplug, addr, status);
152 checkAndClearExceptionFromCallback(sCallbackEnv, __FUNCTION__);
153 sCallbackEnv->DeleteLocalRef(addr);*/
154}
155
156
Matthew Xie35207a52012-03-21 23:11:40 -0700157static bthh_callbacks_t sBluetoothHidCallbacks = {
158 sizeof(sBluetoothHidCallbacks),
159 connection_state_callback,
160 NULL,
Priti Aghera57addcc2012-04-09 12:59:30 -0700161 get_protocol_mode_callback,
broodplank0c589302013-12-29 05:41:41 +0100162 get_idle_time_callback,
Matthew Xie35207a52012-03-21 23:11:40 -0700163 NULL,
Priti Aghera57addcc2012-04-09 12:59:30 -0700164 virtual_unplug_callback
Matthew Xie35207a52012-03-21 23:11:40 -0700165};
166
167// Define native functions
168
169static void classInitNative(JNIEnv* env, jclass clazz) {
170 int err;
fredc6654f5c2012-04-12 00:18:52 -0700171// const bt_interface_t* btInf;
172// bt_status_t status;
Matthew Xie35207a52012-03-21 23:11:40 -0700173
Priti Aghera57addcc2012-04-09 12:59:30 -0700174 method_onConnectStateChanged = env->GetMethodID(clazz, "onConnectStateChanged", "([BI)V");
175 method_onGetProtocolMode = env->GetMethodID(clazz, "onGetProtocolMode", "([BI)V");
broodplank0c589302013-12-29 05:41:41 +0100176 method_onGetIdleTime = env->GetMethodID(clazz, "onGetIdleTime", "([BI)V");
Priti Aghera57addcc2012-04-09 12:59:30 -0700177 method_onVirtualUnplug = env->GetMethodID(clazz, "onVirtualUnplug", "([BI)V");
Matthew Xie35207a52012-03-21 23:11:40 -0700178
fredc6654f5c2012-04-12 00:18:52 -0700179/*
Matthew Xie35207a52012-03-21 23:11:40 -0700180 if ( (btInf = getBluetoothInterface()) == NULL) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700181 ALOGE("Bluetooth module is not loaded");
Matthew Xie35207a52012-03-21 23:11:40 -0700182 return;
183 }
184
185 if ( (sBluetoothHidInterface = (bthh_interface_t *)
186 btInf->get_profile_interface(BT_PROFILE_HIDHOST_ID)) == NULL) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700187 ALOGE("Failed to get Bluetooth Handsfree Interface");
Matthew Xie35207a52012-03-21 23:11:40 -0700188 return;
189 }
190
191 // TODO(BT) do this only once or
192 // Do we need to do this every time the BT reenables?
193 if ( (status = sBluetoothHidInterface->init(&sBluetoothHidCallbacks)) != BT_STATUS_SUCCESS) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700194 ALOGE("Failed to initialize Bluetooth HID, status: %d", status);
Matthew Xie35207a52012-03-21 23:11:40 -0700195 sBluetoothHidInterface = NULL;
196 return;
197 }
198
fredc6654f5c2012-04-12 00:18:52 -0700199*/
Matthew Xiec55a9832012-04-07 03:44:13 -0700200 ALOGI("%s: succeeds", __FUNCTION__);
Matthew Xie35207a52012-03-21 23:11:40 -0700201}
202
fredc6654f5c2012-04-12 00:18:52 -0700203static void initializeNative(JNIEnv *env, jobject object) {
204 const bt_interface_t* btInf;
205 bt_status_t status;
206
207 if ( (btInf = getBluetoothInterface()) == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700208 ALOGE("Bluetooth module is not loaded");
fredc6654f5c2012-04-12 00:18:52 -0700209 return;
210 }
211
212 if (sBluetoothHidInterface !=NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700213 ALOGW("Cleaning up Bluetooth HID Interface before initializing...");
fredc6654f5c2012-04-12 00:18:52 -0700214 sBluetoothHidInterface->cleanup();
215 sBluetoothHidInterface = NULL;
216 }
217
218 if (mCallbacksObj != NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700219 ALOGW("Cleaning up Bluetooth GID callback object");
fredc6654f5c2012-04-12 00:18:52 -0700220 env->DeleteGlobalRef(mCallbacksObj);
221 mCallbacksObj = NULL;
222 }
223
224
225 if ( (sBluetoothHidInterface = (bthh_interface_t *)
226 btInf->get_profile_interface(BT_PROFILE_HIDHOST_ID)) == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700227 ALOGE("Failed to get Bluetooth HID Interface");
fredc6654f5c2012-04-12 00:18:52 -0700228 return;
229 }
230
231 if ( (status = sBluetoothHidInterface->init(&sBluetoothHidCallbacks)) != BT_STATUS_SUCCESS) {
Matthew Xiee469f162012-06-05 23:57:59 -0700232 ALOGE("Failed to initialize Bluetooth HID, status: %d", status);
fredc6654f5c2012-04-12 00:18:52 -0700233 sBluetoothHidInterface = NULL;
234 return;
235 }
236
237
238
Matthew Xie35207a52012-03-21 23:11:40 -0700239 mCallbacksObj = env->NewGlobalRef(object);
240}
241
fredc6654f5c2012-04-12 00:18:52 -0700242static void cleanupNative(JNIEnv *env, jobject object) {
243 const bt_interface_t* btInf;
244 bt_status_t status;
245
246 if ( (btInf = getBluetoothInterface()) == NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700247 ALOGE("Bluetooth module is not loaded");
fredc6654f5c2012-04-12 00:18:52 -0700248 return;
249 }
250
251 if (sBluetoothHidInterface !=NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700252 ALOGW("Cleaning up Bluetooth HID Interface...");
fredc6654f5c2012-04-12 00:18:52 -0700253 sBluetoothHidInterface->cleanup();
254 sBluetoothHidInterface = NULL;
255 }
256
257 if (mCallbacksObj != NULL) {
Matthew Xiee469f162012-06-05 23:57:59 -0700258 ALOGW("Cleaning up Bluetooth GID callback object");
fredc6654f5c2012-04-12 00:18:52 -0700259 env->DeleteGlobalRef(mCallbacksObj);
260 mCallbacksObj = NULL;
261 }
262
263 env->DeleteGlobalRef(mCallbacksObj);
264}
265
Matthew Xie35207a52012-03-21 23:11:40 -0700266static jboolean connectHidNative(JNIEnv *env, jobject object, jbyteArray address) {
267 bt_status_t status;
268 jbyte *addr;
269 jboolean ret = JNI_TRUE;
270 if (!sBluetoothHidInterface) return JNI_FALSE;
271
272 addr = env->GetByteArrayElements(address, NULL);
273 if (!addr) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700274 ALOGE("Bluetooth device address null");
Matthew Xie35207a52012-03-21 23:11:40 -0700275 return JNI_FALSE;
276 }
277
278 if ((status = sBluetoothHidInterface->connect((bt_bdaddr_t *) addr)) !=
279 BT_STATUS_SUCCESS) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700280 ALOGE("Failed HID channel connection, status: %d", status);
Matthew Xie35207a52012-03-21 23:11:40 -0700281 ret = JNI_FALSE;
282 }
283 env->ReleaseByteArrayElements(address, addr, 0);
284
285 return ret;
286}
287
288static jboolean disconnectHidNative(JNIEnv *env, jobject object, jbyteArray address) {
289 bt_status_t status;
290 jbyte *addr;
291 jboolean ret = JNI_TRUE;
292 if (!sBluetoothHidInterface) return JNI_FALSE;
293
294 addr = env->GetByteArrayElements(address, NULL);
295 if (!addr) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700296 ALOGE("Bluetooth device address null");
Matthew Xie35207a52012-03-21 23:11:40 -0700297 return JNI_FALSE;
298 }
299
300 if ( (status = sBluetoothHidInterface->disconnect((bt_bdaddr_t *) addr)) !=
301 BT_STATUS_SUCCESS) {
Matthew Xiec55a9832012-04-07 03:44:13 -0700302 ALOGE("Failed disconnect hid channel, status: %d", status);
Matthew Xie35207a52012-03-21 23:11:40 -0700303 ret = JNI_FALSE;
304 }
305 env->ReleaseByteArrayElements(address, addr, 0);
306
307 return ret;
308}
309
Priti Aghera57addcc2012-04-09 12:59:30 -0700310static jboolean getProtocolModeNative(JNIEnv *env, jobject object, jbyteArray address) {
311 bt_status_t status;
312 jbyte *addr;
313 jboolean ret = JNI_TRUE;
314 bthh_protocol_mode_t protocolMode;
315 if (!sBluetoothHidInterface) return JNI_FALSE;
316
317 addr = env->GetByteArrayElements(address, NULL);
318 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700319 ALOGE("Bluetooth device address null");
Priti Aghera57addcc2012-04-09 12:59:30 -0700320 return JNI_FALSE;
321 }
322
323 if ( (status = sBluetoothHidInterface->get_protocol((bt_bdaddr_t *) addr, (bthh_protocol_mode_t) protocolMode)) !=
324 BT_STATUS_SUCCESS) {
Matthew Xiee469f162012-06-05 23:57:59 -0700325 ALOGE("Failed get protocol mode, status: %d", status);
Priti Aghera57addcc2012-04-09 12:59:30 -0700326 ret = JNI_FALSE;
327 }
328 env->ReleaseByteArrayElements(address, addr, 0);
329
330 return ret;
331}
332
333static jboolean virtualUnPlugNative(JNIEnv *env, jobject object, jbyteArray address) {
334 bt_status_t status;
335 jbyte *addr;
336 jboolean ret = JNI_TRUE;
337 if (!sBluetoothHidInterface) return JNI_FALSE;
338
339 addr = env->GetByteArrayElements(address, NULL);
340 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700341 ALOGE("Bluetooth device address null");
Priti Aghera57addcc2012-04-09 12:59:30 -0700342 return JNI_FALSE;
343 }
344 if ( (status = sBluetoothHidInterface->virtual_unplug((bt_bdaddr_t *) addr)) !=
345 BT_STATUS_SUCCESS) {
Matthew Xiee469f162012-06-05 23:57:59 -0700346 ALOGE("Failed virual unplug, status: %d", status);
Priti Aghera57addcc2012-04-09 12:59:30 -0700347 ret = JNI_FALSE;
348 }
349 env->ReleaseByteArrayElements(address, addr, 0);
350 return ret;
351
352}
353
354
355static jboolean setProtocolModeNative(JNIEnv *env, jobject object, jbyteArray address, jint protocolMode) {
356 bt_status_t status;
357 jbyte *addr;
358 jboolean ret = JNI_TRUE;
359 if (!sBluetoothHidInterface) return JNI_FALSE;
360
Matthew Xiee469f162012-06-05 23:57:59 -0700361 ALOGD("%s: protocolMode = %d", __FUNCTION__, protocolMode);
Priti Aghera57addcc2012-04-09 12:59:30 -0700362
363 addr = env->GetByteArrayElements(address, NULL);
364 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700365 ALOGE("Bluetooth device address null");
Priti Aghera57addcc2012-04-09 12:59:30 -0700366 return JNI_FALSE;
367 }
368
369 bthh_protocol_mode_t mode;
370 switch(protocolMode){
371 case 0:
372 mode = BTHH_REPORT_MODE;
373 break;
374 case 1:
375 mode = BTHH_BOOT_MODE;
376 break;
377 default:
Matthew Xiee469f162012-06-05 23:57:59 -0700378 ALOGE("Unknown HID protocol mode");
Priti Aghera57addcc2012-04-09 12:59:30 -0700379 return JNI_FALSE;
380 }
381 if ( (status = sBluetoothHidInterface->set_protocol((bt_bdaddr_t *) addr, mode)) !=
382 BT_STATUS_SUCCESS) {
Matthew Xiee469f162012-06-05 23:57:59 -0700383 ALOGE("Failed set protocol mode, status: %d", status);
Priti Aghera57addcc2012-04-09 12:59:30 -0700384 ret = JNI_FALSE;
385 }
386 env->ReleaseByteArrayElements(address, addr, 0);
387
388 return JNI_TRUE;
389}
390
391static jboolean getReportNative(JNIEnv *env, jobject object, jbyteArray address, jbyte reportType, jbyte reportId, jint bufferSize) {
Matthew Xiee469f162012-06-05 23:57:59 -0700392 ALOGD("%s: reportType = %d, reportId = %d, bufferSize = %d", __FUNCTION__, reportType, reportId, bufferSize);
Priti Aghera57addcc2012-04-09 12:59:30 -0700393
394 bt_status_t status;
395 jbyte *addr;
396 jboolean ret = JNI_TRUE;
397 if (!sBluetoothHidInterface) return JNI_FALSE;
398
399 addr = env->GetByteArrayElements(address, NULL);
400 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700401 ALOGE("Bluetooth device address null");
Priti Aghera57addcc2012-04-09 12:59:30 -0700402 return JNI_FALSE;
403 }
404
405 jint rType = reportType;
406 jint rId = reportId;
407
408 if ( (status = sBluetoothHidInterface->get_report((bt_bdaddr_t *) addr, (bthh_report_type_t) rType, (uint8_t) rId, bufferSize)) !=
409 BT_STATUS_SUCCESS) {
Matthew Xiee469f162012-06-05 23:57:59 -0700410 ALOGE("Failed get report, status: %d", status);
Priti Aghera57addcc2012-04-09 12:59:30 -0700411 ret = JNI_FALSE;
412 }
413 env->ReleaseByteArrayElements(address, addr, 0);
414
415 return ret;
416}
417
418
419static jboolean setReportNative(JNIEnv *env, jobject object, jbyteArray address, jbyte reportType, jstring report) {
Matthew Xiee469f162012-06-05 23:57:59 -0700420 ALOGD("%s: reportType = %d", __FUNCTION__, reportType);
Priti Aghera57addcc2012-04-09 12:59:30 -0700421 bt_status_t status;
422 jbyte *addr;
423 jboolean ret = JNI_TRUE;
424 if (!sBluetoothHidInterface) return JNI_FALSE;
425
426 addr = env->GetByteArrayElements(address, NULL);
427 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700428 ALOGE("Bluetooth device address null");
Priti Aghera57addcc2012-04-09 12:59:30 -0700429 return JNI_FALSE;
430 }
431 jint rType = reportType;
432 const char *c_report = env->GetStringUTFChars(report, NULL);
433
434 if ( (status = sBluetoothHidInterface->set_report((bt_bdaddr_t *) addr, (bthh_report_type_t)rType, (char*) c_report)) !=
435 BT_STATUS_SUCCESS) {
Matthew Xiee469f162012-06-05 23:57:59 -0700436 ALOGE("Failed set report, status: %d", status);
Priti Aghera57addcc2012-04-09 12:59:30 -0700437 ret = JNI_FALSE;
438 }
439 env->ReleaseStringUTFChars(report, c_report);
440 env->ReleaseByteArrayElements(address, addr, 0);
441
442 return ret;
443}
444
445static jboolean sendDataNative(JNIEnv *env, jobject object, jbyteArray address, jstring report) {
Matthew Xiee469f162012-06-05 23:57:59 -0700446 ALOGD("%s", __FUNCTION__);
Priti Aghera57addcc2012-04-09 12:59:30 -0700447 bt_status_t status;
448 jbyte *addr;
449 jboolean ret = JNI_TRUE;
450 if (!sBluetoothHidInterface) return JNI_FALSE;
451
452 addr = env->GetByteArrayElements(address, NULL);
453 if (!addr) {
Matthew Xiee469f162012-06-05 23:57:59 -0700454 ALOGE("Bluetooth device address null");
Priti Aghera57addcc2012-04-09 12:59:30 -0700455 return JNI_FALSE;
456 }
457 const char *c_report = env->GetStringUTFChars(report, NULL);
458 if ( (status = sBluetoothHidInterface->send_data((bt_bdaddr_t *) addr, (char*) c_report)) !=
459 BT_STATUS_SUCCESS) {
broodplank0c589302013-12-29 05:41:41 +0100460 ALOGE("Failed send data, status: %d", status);
Priti Aghera57addcc2012-04-09 12:59:30 -0700461 ret = JNI_FALSE;
462 }
463 env->ReleaseStringUTFChars(report, c_report);
464 env->ReleaseByteArrayElements(address, addr, 0);
465
466 return ret;
467
468}
469
broodplank0c589302013-12-29 05:41:41 +0100470static jboolean getIdleTimeNative(JNIEnv *env, jobject object, jbyteArray address) {
471 bt_status_t status;
472 jbyte *addr;
473 jboolean ret = JNI_TRUE;
474 if (!sBluetoothHidInterface) return JNI_FALSE;
475
476 addr = env->GetByteArrayElements(address, NULL);
477 if (!addr) {
478 ALOGE("Bluetooth device address null");
479 return JNI_FALSE;
480 }
481
482 if ( (status = sBluetoothHidInterface->get_idle_time((bt_bdaddr_t *) addr)) !=
483 BT_STATUS_SUCCESS) {
484 ALOGE("Failed get idle time, status: %d", status);
485 ret = JNI_FALSE;
486 }
487 env->ReleaseByteArrayElements(address, addr, 0);
488
489 return ret;
490}
491
492static jboolean setIdleTimeNative(JNIEnv *env, jobject object, jbyteArray address, jbyte idle_time) {
493 bt_status_t status;
494 jbyte *addr;
495 jboolean ret = JNI_TRUE;
496 if (!sBluetoothHidInterface) return JNI_FALSE;
497
498 addr = env->GetByteArrayElements(address, NULL);
499 if (!addr) {
500 ALOGE("Bluetooth device address null");
501 return JNI_FALSE;
502 }
503
504 if ( (status = sBluetoothHidInterface->set_idle_time((bt_bdaddr_t *) addr, idle_time)) !=
505 BT_STATUS_SUCCESS) {
506 ALOGE("Failed set idle time, status: %d", status);
507 ret = JNI_FALSE;
508 }
509 env->ReleaseByteArrayElements(address, addr, 0);
510
511 return ret;
512}
513
514static jboolean setPriorityNative(JNIEnv *env, jobject object, jbyteArray address, jint priority) {
515 bt_status_t status;
516 jbyte *addr;
517 jboolean ret = JNI_TRUE;
518 if (!sBluetoothHidInterface) return JNI_FALSE;
519
520 addr = env->GetByteArrayElements(address, NULL);
521 if (!addr) {
522 ALOGE("Bluetooth device address null");
523 return JNI_FALSE;
524 }
525
526 if ( (status = sBluetoothHidInterface->set_priority((bt_bdaddr_t *) addr, priority)) !=
527 BT_STATUS_SUCCESS) {
528 ALOGE("Failed set priority, status: %d", status);
529 ret = JNI_FALSE;
530 }
531 env->ReleaseByteArrayElements(address, addr, 0);
532
533 return ret;
534}
535
536
Matthew Xie35207a52012-03-21 23:11:40 -0700537static JNINativeMethod sMethods[] = {
538 {"classInitNative", "()V", (void *) classInitNative},
fredc6654f5c2012-04-12 00:18:52 -0700539 {"initializeNative", "()V", (void *) initializeNative},
540 {"cleanupNative", "()V", (void *) cleanupNative},
Matthew Xie35207a52012-03-21 23:11:40 -0700541 {"connectHidNative", "([B)Z", (void *) connectHidNative},
542 {"disconnectHidNative", "([B)Z", (void *) disconnectHidNative},
Priti Aghera57addcc2012-04-09 12:59:30 -0700543 {"getProtocolModeNative", "([B)Z", (void *) getProtocolModeNative},
544 {"virtualUnPlugNative", "([B)Z", (void *) virtualUnPlugNative},
545 {"setProtocolModeNative", "([BB)Z", (void *) setProtocolModeNative},
546 {"getReportNative", "([BBBI)Z", (void *) getReportNative},
547 {"setReportNative", "([BBLjava/lang/String;)Z", (void *) setReportNative},
548 {"sendDataNative", "([BLjava/lang/String;)Z", (void *) sendDataNative},
broodplank0c589302013-12-29 05:41:41 +0100549 {"getIdleTimeNative", "([B)Z", (void *) getIdleTimeNative},
550 {"setIdleTimeNative", "([BB)Z", (void *) setIdleTimeNative},
551 {"setPriorityNative", "([BI)Z", (void *) setPriorityNative},
Matthew Xie35207a52012-03-21 23:11:40 -0700552};
553
554int register_com_android_bluetooth_hid(JNIEnv* env)
555{
556 return jniRegisterNativeMethods(env, "com/android/bluetooth/hid/HidService",
557 sMethods, NELEM(sMethods));
558}
559
560}