diff options
author | Hemant Gupta <hemantg@codeaurora.org> | 2013-08-16 15:01:59 +0530 |
---|---|---|
committer | Mike Lockwood <lockwood@google.com> | 2014-07-01 10:36:17 -0700 |
commit | 2c0df0560ad5ae3fd6022b17b17a6a70143e216a (patch) | |
tree | ab4ee6a4af5e86213fb62e54de4b0a9443df93af /jni | |
parent | ee7ff974b660d954ca2f188e54072d410f2b9c2f (diff) | |
download | android_packages_apps_Bluetooth-2c0df0560ad5ae3fd6022b17b17a6a70143e216a.tar.gz android_packages_apps_Bluetooth-2c0df0560ad5ae3fd6022b17b17a6a70143e216a.tar.bz2 android_packages_apps_Bluetooth-2c0df0560ad5ae3fd6022b17b17a6a70143e216a.zip |
Bluetooth: Support MAP Client role on Bluedroid.
Implementation changes to support Message Access Profile
client role in Bluetooth Apk.
Change-Id: I209909a2b18e43c7931571526b983453795f6c6b
Diffstat (limited to 'jni')
-rw-r--r-- | jni/com_android_bluetooth_btservice_AdapterService.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp index 72c3c1c08..78504119f 100644 --- a/jni/com_android_bluetooth_btservice_AdapterService.cpp +++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "BluetoothServiceJni" #include "com_android_bluetooth.h" #include "hardware/bt_sock.h" +#include "hardware/bt_mce.h" #include "utils/Log.h" #include "utils/misc.h" #include "cutils/properties.h" @@ -44,9 +45,11 @@ static jmethodID method_discoveryStateChangeCallback; static jmethodID method_setWakeAlarm; static jmethodID method_acquireWakeLock; static jmethodID method_releaseWakeLock; +static jmethodID method_deviceMasInstancesFoundCallback; static const bt_interface_t *sBluetoothInterface = NULL; static const btsock_interface_t *sBluetoothSocketInterface = NULL; +static const btmce_interface_t *sBluetoothMceInterface = NULL; static JNIEnv *callbackEnv = NULL; static jobject sJniAdapterServiceObj; @@ -563,6 +566,73 @@ static void alarmFiredNative(JNIEnv *env, jobject obj) { sAlarmCallback(sAlarmCallbackData); } +static void remote_mas_instances_callback(bt_status_t status, bt_bdaddr_t *bd_addr, + int num_instances, btmce_mas_instance_t *instances) +{ + if (!checkCallbackThread()) { + ALOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__); + return; + } + + ALOGV("%s: Status is: %d, Instances: %d", __FUNCTION__, status, num_instances); + + if (status != BT_STATUS_SUCCESS) { + ALOGE("%s: Status %d is incorrect", __FUNCTION__, status); + return; + } + + callbackEnv->PushLocalFrame(ADDITIONAL_NREFS); + + jbyteArray addr = NULL; + jobjectArray a_name = NULL; + jintArray a_scn = NULL; + jintArray a_masid = NULL; + jintArray a_msgtype = NULL; + jclass mclass; + + mclass = callbackEnv->FindClass("java/lang/String"); + + addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t)); + if (addr == NULL) goto clean; + + callbackEnv->SetByteArrayRegion(addr, 0, sizeof(bt_bdaddr_t), (jbyte*)bd_addr); + + a_name = callbackEnv->NewObjectArray(num_instances, mclass, NULL); + if (a_name == NULL) goto clean; + + a_scn = callbackEnv->NewIntArray(num_instances); + if (a_scn == NULL) goto clean; + + a_masid = callbackEnv->NewIntArray(num_instances); + if (a_masid == NULL) goto clean; + + a_msgtype = callbackEnv->NewIntArray(num_instances); + if (a_msgtype == NULL) goto clean; + + for (int i = 0; i < num_instances; i++) { + jstring name = callbackEnv->NewStringUTF(instances[i].p_name); + + callbackEnv->SetObjectArrayElement(a_name, i, name); + callbackEnv->SetIntArrayRegion(a_scn, i, 1, &instances[i].scn); + callbackEnv->SetIntArrayRegion(a_masid, i, 1, &instances[i].id); + callbackEnv->SetIntArrayRegion(a_msgtype, i, 1, &instances[i].msg_types); + + callbackEnv->DeleteLocalRef(name); + } + + callbackEnv->CallVoidMethod(sJniCallbacksObj, method_deviceMasInstancesFoundCallback, + (jint) status, addr, a_name, a_scn, a_masid, a_msgtype); + checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__); + +clean: + if (addr != NULL) callbackEnv->DeleteLocalRef(addr); + if (a_name != NULL) callbackEnv->DeleteLocalRef(a_name); + if (a_scn != NULL) callbackEnv->DeleteLocalRef(a_scn); + if (a_masid != NULL) callbackEnv->DeleteLocalRef(a_masid); + if (a_msgtype != NULL) callbackEnv->DeleteLocalRef(a_msgtype); + callbackEnv->PopLocalFrame(NULL); +} + static bt_os_callouts_t sBluetoothOsCallouts = { sizeof(sBluetoothOsCallouts), set_wake_alarm_callout, @@ -570,6 +640,11 @@ static bt_os_callouts_t sBluetoothOsCallouts = { release_wake_lock_callout, }; +static btmce_callbacks_t sBluetoothMceCallbacks = { + sizeof(sBluetoothMceCallbacks), + remote_mas_instances_callback, +}; + static void classInitNative(JNIEnv* env, jclass clazz) { int err; hw_module_t* module; @@ -605,6 +680,9 @@ static void classInitNative(JNIEnv* env, jclass clazz) { method_setWakeAlarm = env->GetMethodID(clazz, "setWakeAlarm", "(JZ)Z"); method_acquireWakeLock = env->GetMethodID(clazz, "acquireWakeLock", "(Ljava/lang/String;)Z"); method_releaseWakeLock = env->GetMethodID(clazz, "releaseWakeLock", "(Ljava/lang/String;)Z"); + method_deviceMasInstancesFoundCallback = env->GetMethodID(jniCallbackClass, + "deviceMasInstancesFoundCallback", + "(I[B[Ljava/lang/String;[I[I[I)V"); char value[PROPERTY_VALUE_MAX]; property_get("bluetooth.mock_stack", value, ""); @@ -652,6 +730,17 @@ static bool initNative(JNIEnv* env, jobject obj) { sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) { ALOGE("Error getting socket interface"); } + + if ( (sBluetoothMceInterface = (btmce_interface_t *) + sBluetoothInterface->get_profile_interface(BT_PROFILE_MAP_CLIENT_ID)) == NULL) { + ALOGE("Error getting mapclient interface"); + } else { + if ( (sBluetoothMceInterface->init(&sBluetoothMceCallbacks)) != BT_STATUS_SUCCESS) { + ALOGE("Failed to initialize Bluetooth MCE"); + sBluetoothMceInterface = NULL; + } + } + return JNI_TRUE; } return JNI_FALSE; @@ -970,6 +1059,25 @@ static jboolean getRemoteServicesNative(JNIEnv *env, jobject obj, jbyteArray add return result; } +static jboolean getRemoteMasInstancesNative(JNIEnv *env, jobject obj, jbyteArray address) { + ALOGV("%s:",__FUNCTION__); + + jbyte *addr = NULL; + jboolean result = JNI_FALSE; + if (!sBluetoothMceInterface) return result; + + addr = env->GetByteArrayElements(address, NULL); + if (addr == NULL) { + jniThrowIOException(env, EINVAL); + return result; + } + + int ret = sBluetoothMceInterface->get_remote_mas_instances((bt_bdaddr_t *)addr); + env->ReleaseByteArrayElements(address, addr, NULL); + result = (ret == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; + return result; +} + static int connectSocketNative(JNIEnv *env, jobject object, jbyteArray address, jint type, jbyteArray uuidObj, jint channel, jint flag) { jbyte *addr = NULL, *uuid = NULL; @@ -1086,6 +1194,7 @@ static JNINativeMethod sMethods[] = { {"pinReplyNative", "([BZI[B)Z", (void*) pinReplyNative}, {"sspReplyNative", "([BIZI)Z", (void*) sspReplyNative}, {"getRemoteServicesNative", "([B)Z", (void*) getRemoteServicesNative}, + {"getRemoteMasInstancesNative", "([B)Z", (void*) getRemoteMasInstancesNative}, {"connectSocketNative", "([BI[BII)I", (void*) connectSocketNative}, {"createSocketChannelNative", "(ILjava/lang/String;[BII)I", (void*) createSocketChannelNative}, |