Loading android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +109 −0 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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; Loading Loading @@ -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, Loading @@ -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; Loading Loading @@ -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, ""); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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}, Loading android/app/src/com/android/bluetooth/btservice/AdapterService.java +19 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ public class AdapterService extends Service { static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; private static final int ADAPTER_SERVICE_TYPE=Service.START_STICKY; Loading Loading @@ -900,6 +901,17 @@ public class AdapterService extends Service { return service.fetchRemoteUuids(device); } public boolean fetchRemoteMasInstances(BluetoothDevice device) { if (!Utils.checkCaller()) { Log.w(TAG,"fetchMasInstances(): not allowed for non-active user"); return false; } AdapterService service = getService(); if (service == null) return false; return service.fetchRemoteMasInstances(device); } public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { if (!Utils.checkCaller()) { Log.w(TAG, "setPin() - Not allowed for non-active user"); Loading Loading @@ -1367,6 +1379,12 @@ public class AdapterService extends Service { return true; } boolean fetchRemoteMasInstances(BluetoothDevice device) { enforceCallingOrSelfPermission(RECEIVE_MAP_PERM, "Need RECEIVE BLUETOOTH MAP permission"); mRemoteDevices.fetchMasInstances(device); return true; } boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); Loading Loading @@ -1607,6 +1625,7 @@ public class AdapterService extends Service { accept, int passkey); /*package*/ native boolean getRemoteServicesNative(byte[] address); /*package*/ native boolean getRemoteMasInstancesNative(byte[] address); // TODO(BT) move this to ../btsock dir private native int connectSocketNative(byte[] address, int type, Loading android/app/src/com/android/bluetooth/btservice/JniCallbacks.java +5 −1 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * Copyright (C) 2012-2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -81,4 +81,8 @@ final class JniCallbacks { mAdapterProperties.adapterPropertyChangedCallback(types, val); } void deviceMasInstancesFoundCallback(int status, byte[] address, String[] name, int[] scn, int[] id, int[] msgtype) { mRemoteDevices.deviceMasInstancesFoundCallback(status, address, name, scn, id, msgtype); } } android/app/src/com/android/bluetooth/btservice/RemoteDevices.java 100755 → 100644 +64 −1 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * Copyright (C) 2012-2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.btservice; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothMasInstance; import android.content.Context; import android.content.Intent; import android.os.Handler; Loading @@ -44,18 +45,23 @@ final class RemoteDevices { private static BluetoothAdapter mAdapter; private static AdapterService mAdapterService; private static ArrayList<BluetoothDevice> mSdpTracker; private static ArrayList<BluetoothDevice> mSdpMasTracker; private Object mObject = new Object(); private static final int UUID_INTENT_DELAY = 6000; private static final int MESSAGE_UUID_INTENT = 1; private static final int MAS_INSTANCE_INTENT_DELAY = 6000; private static final int MESSAGE_MAS_INSTANCE_INTENT = 2; private HashMap<BluetoothDevice, DeviceProperties> mDevices; RemoteDevices(AdapterService service) { mAdapter = BluetoothAdapter.getDefaultAdapter(); mAdapterService = service; mSdpTracker = new ArrayList<BluetoothDevice>(); mSdpMasTracker = new ArrayList<BluetoothDevice>(); mDevices = new HashMap<BluetoothDevice, DeviceProperties>(); } Loading @@ -64,6 +70,9 @@ final class RemoteDevices { if (mSdpTracker !=null) mSdpTracker.clear(); if (mSdpMasTracker != null) mSdpMasTracker.clear(); if (mDevices != null) mDevices.clear(); } Loading Loading @@ -224,6 +233,18 @@ final class RemoteDevices { mSdpTracker.remove(device); } private void sendMasInstanceIntent(BluetoothDevice device, ArrayList<BluetoothMasInstance> instances) { Intent intent = new Intent(BluetoothDevice.ACTION_MAS_INSTANCE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); if (instances != null) intent.putExtra(BluetoothDevice.EXTRA_MAS_INSTANCE, instances); mAdapterService.sendBroadcast(intent, AdapterService.BLUETOOTH_ADMIN_PERM); //Remove the outstanding UUID request mSdpMasTracker.remove(device); } private void sendDisplayPinIntent(byte[] address, int pin) { Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, getDevice(address)); Loading Loading @@ -429,6 +450,31 @@ final class RemoteDevices { mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_PERM); } void deviceMasInstancesFoundCallback(int status, byte[] address, String[] name, int[] scn, int[] id, int[] msgtype) { BluetoothDevice device = getDevice(address); if (device == null) { errorLog("deviceMasInstancesFoundCallback: Device is NULL"); return; } debugLog("deviceMasInstancesFoundCallback: found " + name.length + " instances"); ArrayList<BluetoothMasInstance> instances = new ArrayList<BluetoothMasInstance>(); for (int i = 0; i < name.length; i++) { BluetoothMasInstance inst = new BluetoothMasInstance(id[i], name[i], scn[i], msgtype[i]); debugLog(inst.toString()); instances.add(inst); } sendMasInstanceIntent(device, instances); } void fetchUuids(BluetoothDevice device) { if (mSdpTracker.contains(device)) return; mSdpTracker.add(device); Loading @@ -441,6 +487,17 @@ final class RemoteDevices { mAdapterService.getRemoteServicesNative(Utils.getBytesFromAddress(device.getAddress())); } void fetchMasInstances(BluetoothDevice device) { if (mSdpMasTracker.contains(device)) return; mSdpMasTracker.add(device); Message message = mHandler.obtainMessage(MESSAGE_MAS_INSTANCE_INTENT); message.obj = device; mHandler.sendMessageDelayed(message, MAS_INSTANCE_INTENT_DELAY); mAdapterService.getRemoteMasInstancesNative(Utils.getBytesFromAddress(device.getAddress())); } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { Loading @@ -451,6 +508,12 @@ final class RemoteDevices { sendUuidIntent(device); } break; case MESSAGE_MAS_INSTANCE_INTENT: BluetoothDevice dev = (BluetoothDevice)msg.obj; if (dev != null) { sendMasInstanceIntent(dev, null); } break; } } }; Loading Loading
android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +109 −0 Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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; Loading Loading @@ -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, Loading @@ -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; Loading Loading @@ -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, ""); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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}, Loading
android/app/src/com/android/bluetooth/btservice/AdapterService.java +19 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ public class AdapterService extends Service { static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; private static final int ADAPTER_SERVICE_TYPE=Service.START_STICKY; Loading Loading @@ -900,6 +901,17 @@ public class AdapterService extends Service { return service.fetchRemoteUuids(device); } public boolean fetchRemoteMasInstances(BluetoothDevice device) { if (!Utils.checkCaller()) { Log.w(TAG,"fetchMasInstances(): not allowed for non-active user"); return false; } AdapterService service = getService(); if (service == null) return false; return service.fetchRemoteMasInstances(device); } public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { if (!Utils.checkCaller()) { Log.w(TAG, "setPin() - Not allowed for non-active user"); Loading Loading @@ -1367,6 +1379,12 @@ public class AdapterService extends Service { return true; } boolean fetchRemoteMasInstances(BluetoothDevice device) { enforceCallingOrSelfPermission(RECEIVE_MAP_PERM, "Need RECEIVE BLUETOOTH MAP permission"); mRemoteDevices.fetchMasInstances(device); return true; } boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); Loading Loading @@ -1607,6 +1625,7 @@ public class AdapterService extends Service { accept, int passkey); /*package*/ native boolean getRemoteServicesNative(byte[] address); /*package*/ native boolean getRemoteMasInstancesNative(byte[] address); // TODO(BT) move this to ../btsock dir private native int connectSocketNative(byte[] address, int type, Loading
android/app/src/com/android/bluetooth/btservice/JniCallbacks.java +5 −1 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * Copyright (C) 2012-2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -81,4 +81,8 @@ final class JniCallbacks { mAdapterProperties.adapterPropertyChangedCallback(types, val); } void deviceMasInstancesFoundCallback(int status, byte[] address, String[] name, int[] scn, int[] id, int[] msgtype) { mRemoteDevices.deviceMasInstancesFoundCallback(status, address, name, scn, id, msgtype); } }
android/app/src/com/android/bluetooth/btservice/RemoteDevices.java 100755 → 100644 +64 −1 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * Copyright (C) 2012-2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.btservice; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothMasInstance; import android.content.Context; import android.content.Intent; import android.os.Handler; Loading @@ -44,18 +45,23 @@ final class RemoteDevices { private static BluetoothAdapter mAdapter; private static AdapterService mAdapterService; private static ArrayList<BluetoothDevice> mSdpTracker; private static ArrayList<BluetoothDevice> mSdpMasTracker; private Object mObject = new Object(); private static final int UUID_INTENT_DELAY = 6000; private static final int MESSAGE_UUID_INTENT = 1; private static final int MAS_INSTANCE_INTENT_DELAY = 6000; private static final int MESSAGE_MAS_INSTANCE_INTENT = 2; private HashMap<BluetoothDevice, DeviceProperties> mDevices; RemoteDevices(AdapterService service) { mAdapter = BluetoothAdapter.getDefaultAdapter(); mAdapterService = service; mSdpTracker = new ArrayList<BluetoothDevice>(); mSdpMasTracker = new ArrayList<BluetoothDevice>(); mDevices = new HashMap<BluetoothDevice, DeviceProperties>(); } Loading @@ -64,6 +70,9 @@ final class RemoteDevices { if (mSdpTracker !=null) mSdpTracker.clear(); if (mSdpMasTracker != null) mSdpMasTracker.clear(); if (mDevices != null) mDevices.clear(); } Loading Loading @@ -224,6 +233,18 @@ final class RemoteDevices { mSdpTracker.remove(device); } private void sendMasInstanceIntent(BluetoothDevice device, ArrayList<BluetoothMasInstance> instances) { Intent intent = new Intent(BluetoothDevice.ACTION_MAS_INSTANCE); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); if (instances != null) intent.putExtra(BluetoothDevice.EXTRA_MAS_INSTANCE, instances); mAdapterService.sendBroadcast(intent, AdapterService.BLUETOOTH_ADMIN_PERM); //Remove the outstanding UUID request mSdpMasTracker.remove(device); } private void sendDisplayPinIntent(byte[] address, int pin) { Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, getDevice(address)); Loading Loading @@ -429,6 +450,31 @@ final class RemoteDevices { mAdapterService.sendBroadcast(intent, mAdapterService.BLUETOOTH_PERM); } void deviceMasInstancesFoundCallback(int status, byte[] address, String[] name, int[] scn, int[] id, int[] msgtype) { BluetoothDevice device = getDevice(address); if (device == null) { errorLog("deviceMasInstancesFoundCallback: Device is NULL"); return; } debugLog("deviceMasInstancesFoundCallback: found " + name.length + " instances"); ArrayList<BluetoothMasInstance> instances = new ArrayList<BluetoothMasInstance>(); for (int i = 0; i < name.length; i++) { BluetoothMasInstance inst = new BluetoothMasInstance(id[i], name[i], scn[i], msgtype[i]); debugLog(inst.toString()); instances.add(inst); } sendMasInstanceIntent(device, instances); } void fetchUuids(BluetoothDevice device) { if (mSdpTracker.contains(device)) return; mSdpTracker.add(device); Loading @@ -441,6 +487,17 @@ final class RemoteDevices { mAdapterService.getRemoteServicesNative(Utils.getBytesFromAddress(device.getAddress())); } void fetchMasInstances(BluetoothDevice device) { if (mSdpMasTracker.contains(device)) return; mSdpMasTracker.add(device); Message message = mHandler.obtainMessage(MESSAGE_MAS_INSTANCE_INTENT); message.obj = device; mHandler.sendMessageDelayed(message, MAS_INSTANCE_INTENT_DELAY); mAdapterService.getRemoteMasInstancesNative(Utils.getBytesFromAddress(device.getAddress())); } private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { Loading @@ -451,6 +508,12 @@ final class RemoteDevices { sendUuidIntent(device); } break; case MESSAGE_MAS_INSTANCE_INTENT: BluetoothDevice dev = (BluetoothDevice)msg.obj; if (dev != null) { sendMasInstanceIntent(dev, null); } break; } } }; Loading