com_android_bluetooth_btservice_AdapterService.cpp revision ff4f17bf64978d0738c66e1b6dd70be8664efc24
1ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
2ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * Copyright (C) 2012 Google Inc.
3ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
4ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
5ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#define LOG_TAG "BluetoothServiceJni"
6ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
7ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "JNIHelp.h"
8ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "jni.h"
9ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "hardware/hardware.h"
10ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "hardware/bluetooth.h"
11ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/Log.h"
12ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "utils/misc.h"
13ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "cutils/properties.h"
14ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include "android_runtime/AndroidRuntime.h"
15ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
16ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <string.h>
17ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <pthread.h>
18ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
19ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <sys/stat.h>
20ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh#include <fcntl.h>
21ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
22ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshnamespace android {
23ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
24ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_stateChangeCallback;
25ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_adapterPropertyChangedCallback;
26ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_devicePropertyChangedCallback;
27ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_deviceFoundCallback;
28ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_pinRequestCallback;
29ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_passkeyRequestCallback;
30ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_sspRequestCallback;
31ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_bondStateChangeCallback;
32ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jmethodID method_discoveryStateChangeCallback;
33ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
34ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic const bt_interface_t *sBluetoothInterface = NULL;
35ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNIEnv *callbackEnv = NULL;
36ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
37ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jobject sJniCallbacksObj;
38ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jfieldID sJniCallbacksField;
39ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
40ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void checkAndClearExceptionFromCallback(JNIEnv* env,
41ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                               const char* methodName) {
42ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (env->ExceptionCheck()) {
43ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("An exception was thrown by callback '%s'.", methodName);
44ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE_EX(env);
45ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->ExceptionClear();
46ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
47ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
48ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
49ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool checkCallbackThread() {
50ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JNIEnv* env = AndroidRuntime::getJNIEnv();
51ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (callbackEnv != env || callbackEnv == NULL) return false;
52ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return true;
53ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
54ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
55ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_state_change_callback(bt_state_t status) {
56ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
57ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
58ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
59ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
60ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Status is: %d", __FUNCTION__, status);
61ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
62ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_stateChangeCallback, (jint)status);
63ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
64ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
65ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
66ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
67ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic int get_properties(int num_properties, bt_property_t *properties, jintArray *types,
68ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                        jobjectArray *props) {
69ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray propVal, val;
70ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
71ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (val == NULL) goto Fail;
72ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
73ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    //TODO(BT) Is this the best way to do it ?
74ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    *props = callbackEnv->NewObjectArray(num_properties, callbackEnv->GetObjectClass(val),
75ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                             NULL);
76ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (*props == NULL) goto Fail;
77ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
78ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    *types = callbackEnv->NewIntArray(num_properties);
79ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (*types == NULL) goto Fail;
80ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
81ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
82ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       propVal = callbackEnv->NewByteArray(properties[i].len);
83ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       if (propVal == NULL) goto Fail;
84ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
85ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetByteArrayRegion(propVal, 0, properties[i].len,
86ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                            (jbyte*)properties[i].val);
87ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetObjectArrayElement(*props, i, propVal);
88ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
89ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       callbackEnv->SetIntArrayRegion(*types, i, 1, (jint *)&properties[i].type);
90ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
91ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return 0;
92ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
93ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (val) callbackEnv->DeleteLocalRef(val);
94ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (propVal) callbackEnv->DeleteLocalRef(propVal);
95ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocation of array in %s", __FUNCTION__);
96ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return -1;
97ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
98ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
99ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void adapter_properties_callback(bt_status_t status, int num_properties,
100ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_property_t *properties) {
101ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jobjectArray props;
102ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jintArray types;
103ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
104ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
105ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
106ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
107ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
108ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
109ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
110ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
111ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("%s: Status %d is incorrect", __FUNCTION__, status);
112ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
113ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
114ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
115ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!get_properties(num_properties, properties, &types, &props)) {
116ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
117ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
118ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
119ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
120ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
121ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_adapterPropertyChangedCallback, types,
122ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                props);
123ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
124ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
125ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
126ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
127ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
128ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void remote_device_properties_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
129ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              int num_properties, bt_property_t *properties) {
130ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jobjectArray props;
131ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr = NULL;
132ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jintArray types;
133ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
134ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
135ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
136ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
137ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
138ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
139ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Status is: %d, Properties: %d", __FUNCTION__, status, num_properties);
140ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
141ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (status != BT_STATUS_SUCCESS) {
142ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("%s: Status %d is incorrect", __FUNCTION__, status);
143ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
144ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
145ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
146ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
147ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
148ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
149ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
150ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!get_properties(num_properties, properties, &types, &props)) {
151ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (props) callbackEnv->DeleteLocalRef(props);
152ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (types) callbackEnv->DeleteLocalRef(types);
153ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
154ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
155ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
156ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_devicePropertyChangedCallback, addr,
157ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                types, props);
158ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
159ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
160ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
161ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
162ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocation byte array in %s", __FUNCTION__);
163ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
164ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
165ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
166ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void device_found_callback(int num_properties, bt_property_t *properties) {
167ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr = NULL;
168ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int addr_index;
169ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
170ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    for (int i = 0; i < num_properties; i++) {
171ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (properties[i].type == BT_PROPERTY_BDADDR) {
172ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            addr = callbackEnv->NewByteArray(properties[i].len);
173ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            if (addr) {
174ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                callbackEnv->SetByteArrayRegion(addr, 0, properties[i].len,
175ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                (jbyte*)properties[i].val);
176ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                addr_index = i;
177ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            } else {
178ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                LOGE("Address is NULL (unable to allocate) in %s", __FUNCTION__);
179ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                return;
180ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            }
181ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
182ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
183ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
184ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is NULL in %s", __FUNCTION__);
185ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
186ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
187ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
188ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: Properties: %d, Address: %s", __FUNCTION__, num_properties,
189ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        (const char *)properties[addr_index].val);
190ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
191ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    remote_device_properties_callback(BT_STATUS_SUCCESS, (bt_bdaddr_t *)properties[addr_index].val,
192ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                      num_properties, properties);
193ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
194ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceFoundCallback, addr);
195ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
196ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
197ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
198ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void bond_state_changed_callback(bt_status_t status, bt_bdaddr_t *bd_addr,
199ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        bt_bond_state_t state) {
200ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
201ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int i;
202ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
203ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
204ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
205ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
206ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
207ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is null in %s", __FUNCTION__);
208ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
209ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
210ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
211ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
212ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Address allocation failed in %s", __FUNCTION__);
213ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
214ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
215ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
216ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
217ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_bondStateChangeCallback, (jint) status,
218ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                addr, (jint)state);
219ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
220ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
221ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
222ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
223ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void discovery_state_changed_callback(bt_discovery_state_t state) {
224ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr;
225ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
226ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
227ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
228ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
229ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
230ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s: DiscoveryState:%d ", __FUNCTION__, state);
231ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
232ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_discoveryStateChangeCallback,
233ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint)state);
234ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
235ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
236ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
237ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
238ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void pin_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod) {
239ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
240ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
241ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
242ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
243ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
244ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
245ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is null in %s", __FUNCTION__);
246ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
247ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
248ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
249ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
250ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
251ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdname_t), (jbyte*)bd_addr);
252ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
253ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
254ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
255ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
256ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
257ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
258ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_pinRequestCallback, addr, devname, cod);
259ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
260ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
261ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
262ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
263ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
264ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
265ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
266ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocating in: %s", __FUNCTION__);
267ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
268ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
269ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void passkey_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod) {
270ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
271ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
272ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
273ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
274ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
275ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
276ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is null in %s", __FUNCTION__);
277ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
278ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
279ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
280ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
281ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr);
282ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
283ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
284ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
285ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
286ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
287ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_passkeyRequestCallback, addr, devname,
288ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                cod);
289ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
290ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
291ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
292ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
293ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
294ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
295ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
296ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
297ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocating in: %s", __FUNCTION__);
298ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
299ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
300ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void ssp_request_callback(bt_bdaddr_t *bd_addr, bt_bdname_t *bdname, uint32_t cod,
301ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                 bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
302ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyteArray addr, devname;
303ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!checkCallbackThread()) {
304ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
305ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh       return;
306ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
307ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!bd_addr) {
308ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("Address is null in %s", __FUNCTION__);
309ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return;
310ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
311ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
312ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
313ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) goto Fail;
314ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte *)bd_addr);
315ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
316ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    devname = callbackEnv->NewByteArray(sizeof(bt_bdname_t));
317ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname == NULL) goto Fail;
318ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->SetByteArrayRegion(devname, 0, sizeof(bt_bdname_t), (jbyte*)bdname);
319ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
320ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callbackEnv->CallVoidMethod(sJniCallbacksObj, method_sspRequestCallback, addr, devname, cod,
321ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                (jint) pairing_variant, pass_key);
322ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
323ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
324ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return;
325ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
326ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar GaneshFail:
327ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr) callbackEnv->DeleteLocalRef(addr);
328ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (devname) callbackEnv->DeleteLocalRef(devname);
329ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
330ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGE("Error while allocating in: %s", __FUNCTION__);
331ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
332ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
333ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void callback_thread_event(bt_cb_thread_evt event) {
334ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    JavaVM* vm = AndroidRuntime::getJavaVM();
335ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (event  == ASSOCIATE_JVM) {
336ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        JavaVMAttachArgs args;
337ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        char name[] = "BT Service Callback Thread";
338ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        //TODO(BT)
339ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        //args.version = nat->envVer;
340ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.name = name;
341ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        args.group = NULL;
342ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->AttachCurrentThread(&callbackEnv, &args);
343ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGV("Callback thread attached: %p", callbackEnv);
344ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else if (event == DISASSOCIATE_JVM) {
345ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (!checkCallbackThread()) {
346ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
347ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return;
348ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
349ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        vm->DetachCurrentThread();
350ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
351ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
352ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
353ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshbt_callbacks_t sBluetoothCallbacks = {
354ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sizeof(sBluetoothCallbacks),
355ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    adapter_state_change_callback,
356ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    adapter_properties_callback,
357ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    remote_device_properties_callback,
358ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    device_found_callback,
359ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    discovery_state_changed_callback,
360ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    pin_request_callback,
361ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    passkey_request_callback,
362ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    ssp_request_callback,
363ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bond_state_changed_callback,
364ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    callback_thread_event,
365ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
366ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
367ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic void classInitNative(JNIEnv* env, jclass clazz) {
368ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int err;
369ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    hw_module_t* module;
370ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
371ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jclass jniCallbackClass =
372ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->FindClass("com/android/bluetooth/btservice/JniCallbacks");
373ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksField = env->GetFieldID(clazz, "mJniCallbacks",
374ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        "Lcom/android/bluetooth/btservice/JniCallbacks;");
375ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
376ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_stateChangeCallback = env->GetMethodID(jniCallbackClass, "stateChangeCallback", "(I)V");
377ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
378ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_adapterPropertyChangedCallback = env->GetMethodID(jniCallbackClass,
379ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "adapterPropertyChangedCallback",
380ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                             "([I[[B)V");
381ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_discoveryStateChangeCallback = env->GetMethodID(jniCallbackClass,
382ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                           "discoveryStateChangeCallback", "(I)V");
383ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
384ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_devicePropertyChangedCallback = env->GetMethodID(jniCallbackClass,
385ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "devicePropertyChangedCallback",
386ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                            "([B[I[[B)V");
387ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V");
388ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_pinRequestCallback = env->GetMethodID(jniCallbackClass, "pinRequestCallback",
389ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BI)V");
390ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_passkeyRequestCallback = env->GetMethodID(jniCallbackClass, "passkeyRequestCallback",
391ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                     "([B[BI)V");
392ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_sspRequestCallback = env->GetMethodID(jniCallbackClass, "sspRequestCallback",
393ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                 "([B[BIII)V");
394ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
395ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    method_bondStateChangeCallback = env->GetMethodID(jniCallbackClass,
396ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                     "bondStateChangeCallback", "(I[BI)V");
397ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
398ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    char value[PROPERTY_VALUE_MAX];
399ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    property_get("bluetooth.mock_stack", value, "");
400ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
401ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    const char *id = (strcmp(value, "1")? BT_STACK_MODULE_ID : BT_STACK_TEST_MODULE_ID);
402ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
403ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    err = hw_get_module(id, (hw_module_t const**)&module);
404ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
405ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (err == 0) {
406ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        hw_device_t* abstraction;
407ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        err = module->methods->open(module, id, &abstraction);
408ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (err == 0) {
409ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            bluetooth_module_t* btStack = (bluetooth_module_t *)abstraction;
410ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = btStack->get_bluetooth_interface();
411ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        } else {
412ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           LOGE("Error while opening Bluetooth library");
413ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
414ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    } else {
415ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        LOGE("No Bluetooth Library found");
416ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
417ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
418ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
419ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool initNative(JNIEnv* env, jobject obj) {
420ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
421ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
422ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
423ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
424ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (sBluetoothInterface) {
425ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        int ret = sBluetoothInterface->init(&sBluetoothCallbacks);
426ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (ret != BT_STATUS_SUCCESS) {
427ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            LOGE("Error while setting the callbacks \n");
428ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            sBluetoothInterface = NULL;
429ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh            return JNI_FALSE;
430ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
431ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_TRUE;
432ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
433ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_FALSE;
434ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
435ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
436ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic bool cleanupNative(JNIEnv *env, jobject obj) {
437ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
438ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
439ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
440ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
441ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
442ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    sBluetoothInterface->cleanup();
443ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->DeleteGlobalRef(sJniCallbacksObj);
444ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return JNI_TRUE;
445ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
446ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
447ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean enableNative(JNIEnv* env, jobject obj) {
448ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
449ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
450ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
451ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
452ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
453ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->enable();
454ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
455ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
456ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
457ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
458ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean disableNative(JNIEnv* env, jobject obj) {
459ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
460ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
461ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
462ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
463ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
464ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->disable();
465ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
466ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
467ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
468ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
469ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
470ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
471ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
472ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
473ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
474ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
475ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->start_discovery();
476ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
477ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
478ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
479ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
480ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelDiscoveryNative(JNIEnv* env, jobject obj) {
481ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
482ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
483ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
484ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
485ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
486ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_discovery();
487ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
488ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
489ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
490ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
491ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean createBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
492ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
493ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
494ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
495ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
496ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
497ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
498ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
499ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
500ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
501ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
502ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
503ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
504ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
505ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->create_bond((bt_bdaddr_t *)addr);
506ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
507ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
508ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
509ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
510ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
511ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
512ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean removeBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
513ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
514ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
515ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
516ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
517ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
518ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
519ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
520ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
521ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
522ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
523ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
524ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
525ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->remove_bond((bt_bdaddr_t *)addr);
526ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
527ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
528ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
529ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
530ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
531ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
532ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean cancelBondNative(JNIEnv* env, jobject obj, jbyteArray address) {
533ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
534ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
535ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
536ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result;
537ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return JNI_FALSE;
538ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
539ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
540ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
541ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
542ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return JNI_FALSE;
543ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
544ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
545ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->cancel_bond((bt_bdaddr_t *)addr);
546ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
547ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
548ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
549ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
550ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
551ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
552ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean pinReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
553ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                               jint len, jbyteArray pinArray) {
554ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
555ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
556ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr, *pinPtr = NULL;
557ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
558ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
559ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
560ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
561ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
562ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
563ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
564ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
565ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
566ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (accept) {
567ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        pinPtr = env->GetByteArrayElements(pinArray, NULL);
568ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        if (pinPtr == NULL) {
569ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           jniThrowIOException(env, EINVAL);
570ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           env->ReleaseByteArrayElements(address, addr, NULL);
571ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh           return result;
572ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        }
573ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
574ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
575ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->pin_reply((bt_bdaddr_t*)addr, accept, len,
576ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                              (bt_pin_code_t *) pinPtr);
577ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
578ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(pinArray, pinPtr, NULL);
579ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
580ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
581ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
582ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
583ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
584ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean passkeyReplyNative(JNIEnv *env, jobject obj, jbyteArray address, jboolean accept,
585ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                               jint len, uint32_t passkey) {
586ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
587ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
588ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr = NULL;
589ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
590ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
591ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
592ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
593ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
594ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
595ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
596ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
597ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
598ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->passkey_reply((bt_bdaddr_t *)addr, accept, passkey);
599ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
600ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
601ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
602ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
603ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
604ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
605ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean sspReplyNative(JNIEnv *env, jobject obj, jbyteArray address,
606ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                               jboolean accept) {
607ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
608ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
609ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr;
610ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
611ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
612ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
613ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
614ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
615ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
616ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
617ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
618ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
619ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->ssp_reply((bt_bdaddr_t *)addr, accept);
620ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
621ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
622ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
623ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
624ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
625ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
626ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setAdapterPropertyNative(JNIEnv *env, jobject obj, jint type, jbyteArray value) {
627ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
628ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
629ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val;
630ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
631ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
632ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
633ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
634ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
635ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
636ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
637ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
638ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
639ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_adapter_property(&prop);
640ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(value, val, NULL);
641ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
642ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
643ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
644ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
645ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
646ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertiesNative(JNIEnv *env, jobject obj) {
647ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
648ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
649ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
650ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
651ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
652ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_properties();
653ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
654ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
655ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
656ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
657ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
658ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getAdapterPropertyNative(JNIEnv *env, jobject obj, jint type) {
659ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
660ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
661ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
662ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
663ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
664ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_adapter_property((bt_property_type_t) type);
665ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
666ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
667ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
668ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
669ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
670ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean getDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address, jint type) {
671ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
672ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
673ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *addr = NULL;
674ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
675ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
676ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
677ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
678ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
679ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
680ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
681ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
682ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
683ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->get_remote_device_property((bt_bdaddr_t *)addr,
684ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                                              (bt_property_type_t) type);
685ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
686ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
687ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
688ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
689ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
690ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
691ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic jboolean setDevicePropertyNative(JNIEnv *env, jobject obj, jbyteArray address,
692ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                        jint type, jbyteArray value) {
693ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    LOGV("%s:",__FUNCTION__);
694ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
695ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jbyte *val, *addr;
696ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    jboolean result = JNI_FALSE;
697ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (!sBluetoothInterface) return result;
698ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
699ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    val = env->GetByteArrayElements(value, NULL);
700ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (val == NULL) {
701ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
702ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
703ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
704ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
705ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    addr = env->GetByteArrayElements(address, NULL);
706ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    if (addr == NULL) {
707ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        env->ReleaseByteArrayElements(value, val, NULL);
708ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        jniThrowIOException(env, EINVAL);
709ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh        return result;
710ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    }
711ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
712ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
713ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    bt_property_t prop;
714ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.type = (bt_property_type_t) type;
715ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.len = env->GetArrayLength(value);
716ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    prop.val = val;
717ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
718ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    int ret = sBluetoothInterface->set_remote_device_property((bt_bdaddr_t *)addr, &prop);
719ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(value, val, NULL);
720ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    env->ReleaseByteArrayElements(address, addr, NULL);
721ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
722ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE;
723ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
724ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return result;
725ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
726ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
727ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshstatic JNINativeMethod sMethods[] = {
728ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh     /* name, signature, funcPtr */
729ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"classInitNative", "()V", (void *) classInitNative},
730ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"initNative", "()Z", (void *) initNative},
731ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cleanupNative", "()V", (void*) cleanupNative},
732ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"enableNative", "()Z",  (void*) enableNative},
733ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"disableNative", "()Z",  (void*) disableNative},
734ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setAdapterPropertyNative", "(I[B)Z", (void*) setAdapterPropertyNative},
735ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertiesNative", "()Z", (void*) getAdapterPropertiesNative},
736ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getAdapterPropertyNative", "(I)Z", (void*) getAdapterPropertyNative},
737ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"getDevicePropertyNative", "([BI)Z", (void*) getDevicePropertyNative},
738ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"setDevicePropertyNative", "([BI[B)Z", (void*) setDevicePropertyNative},
739ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"startDiscoveryNative", "()Z", (void*) startDiscoveryNative},
740ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelDiscoveryNative", "()Z", (void*) cancelDiscoveryNative},
741ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"createBondNative", "([B)Z", (void*) createBondNative},
742ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"removeBondNative", "([B)Z", (void*) removeBondNative},
743ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"cancelBondNative", "([B)Z", (void*) cancelBondNative},
744ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative},
745ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"passkeyReplyNative", "([BZII)Z", (void*) passkeyReplyNative},
746ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    {"sspReplyNative", "([BZ)Z", (void*) sspReplyNative},
747ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh};
748ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
749ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshint register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
750ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
751ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh    return jniRegisterNativeMethods(env, "com/android/bluetooth/btservice/AdapterService",
752ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh                                    sMethods, NELEM(sMethods));
753ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
754ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
755ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh} /* namespace android */
756ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
757ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
758ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh/*
759ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh * JNI Initialization
760ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh */
761ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganeshjint JNI_OnLoad(JavaVM *jvm, void *reserved)
762ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh{
763ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   JNIEnv *e;
764ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
765ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   LOGV("Bluetooth Adapter Service : loading JNI\n");
766ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
767ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   // Check JNI version
768ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   if(jvm->GetEnv((void **)&e, JNI_VERSION_1_6))
769ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh      return JNI_ERR;
770ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh
771ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   if (android::register_com_android_bluetooth_btservice_AdapterService(e) == -1)
772ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh      return JNI_ERR;
773ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh   return JNI_VERSION_1_6;
774ff4f17bf64978d0738c66e1b6dd70be8664efc24Jaikumar Ganesh}
775