summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaikumar Ganesh <jaikumar@google.com>2010-12-13 13:42:42 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-12-13 13:42:42 -0800
commitfaaddc632f01ed148dfe1dd9c38f69524ab099e9 (patch)
treef02f383fd7ec6f1940c71ef98311ccf863a856d1
parenta60f00ffec251a13544973f43bf10df2b3e90011 (diff)
parent84690c88f37f395094147d27ace8319a2803a522 (diff)
downloadframeworks_base-faaddc632f01ed148dfe1dd9c38f69524ab099e9.zip
frameworks_base-faaddc632f01ed148dfe1dd9c38f69524ab099e9.tar.gz
frameworks_base-faaddc632f01ed148dfe1dd9c38f69524ab099e9.tar.bz2
Merge "Add direct calls to Bluez to add SDP records."
-rw-r--r--core/java/android/bluetooth/BluetoothUuid.java19
-rw-r--r--core/java/android/server/BluetoothEventLoop.java2
-rw-r--r--core/java/android/server/BluetoothService.java92
-rw-r--r--core/jni/android_server_BluetoothService.cpp75
4 files changed, 134 insertions, 54 deletions
diff --git a/core/java/android/bluetooth/BluetoothUuid.java b/core/java/android/bluetooth/BluetoothUuid.java
index 3fbfc70..5962235 100644
--- a/core/java/android/bluetooth/BluetoothUuid.java
+++ b/core/java/android/bluetooth/BluetoothUuid.java
@@ -20,6 +20,7 @@ import android.os.ParcelUuid;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.UUID;
/**
* Static helper methods and constants to decode the ParcelUuid of remote devices.
@@ -41,8 +42,12 @@ public final class BluetoothUuid {
ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid HSP =
ParcelUuid.fromString("00001108-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid HSP_AG =
+ ParcelUuid.fromString("00001112-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid Handsfree =
ParcelUuid.fromString("0000111E-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid Handsfree_AG =
+ ParcelUuid.fromString("0000111F-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AvrcpController =
ParcelUuid.fromString("0000110E-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid AvrcpTarget =
@@ -57,6 +62,8 @@ public final class BluetoothUuid {
ParcelUuid.fromString("00001116-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid BNEP =
ParcelUuid.fromString("0000000f-0000-1000-8000-00805F9B34FB");
+ public static final ParcelUuid PBAP_PSE =
+ ParcelUuid.fromString("0000112f-0000-1000-8000-00805F9B34FB");
public static final ParcelUuid[] RESERVED_UUIDS = {
AudioSink, AudioSource, AdvAudioDist, HSP, Handsfree, AvrcpController, AvrcpTarget,
@@ -173,4 +180,16 @@ public final class BluetoothUuid {
return true;
}
+ /**
+ * Extract the Service Identifier or the actual uuid from the Parcel Uuid.
+ * For example, if 0000110B-0000-1000-8000-00805F9B34FB is the parcel Uuid,
+ * this function will return 110B
+ * @param parcelUuid
+ * @return the service identifier.
+ */
+ public static int getServiceIdentifierFromParcelUuid(ParcelUuid parcelUuid) {
+ UUID uuid = parcelUuid.getUuid();
+ long value = (uuid.getMostSignificantBits() & 0x0000FFFF00000000L) >>> 32;
+ return (int)value;
+ }
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 4f56281..529e6b8 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -293,7 +293,7 @@ class BluetoothEventLoop {
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
}
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
- } else if (name.equals("Devices")) {
+ } else if (name.equals("Devices") || name.equals("UUIDs")) {
String value = null;
int len = Integer.valueOf(propValues[1]);
if (len > 0) {
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 398b5ae..76f0d72 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -97,6 +97,8 @@ public class BluetoothService extends IBluetooth.Stub {
private boolean mRestart = false; // need to call enable() after disable()
private boolean mIsDiscovering;
private boolean mTetheringOn;
+ private int[] mAdapterSdpUuids;
+ private int[] mAdapterSdpHandles;
private BluetoothAdapter mAdapter; // constant after init()
private final BondState mBondState = new BondState(); // local cache of bondings
@@ -112,11 +114,10 @@ public class BluetoothService extends IBluetooth.Stub {
private static final String SHARED_PREFERENCE_DOCK_ADDRESS = "dock_bluetooth_address";
private static final String SHARED_PREFERENCES_NAME = "bluetooth_service_settings";
- private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
- private static final int MESSAGE_FINISH_DISABLE = 2;
- private static final int MESSAGE_UUID_INTENT = 3;
- private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 4;
- private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 5;
+ private static final int MESSAGE_FINISH_DISABLE = 1;
+ private static final int MESSAGE_UUID_INTENT = 2;
+ private static final int MESSAGE_DISCOVERABLE_TIMEOUT = 3;
+ private static final int MESSAGE_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 4;
// The time (in millisecs) to delay the pairing attempt after the first
// auto pairing attempt fails. We use an exponential delay with
@@ -378,8 +379,10 @@ public class BluetoothService extends IBluetooth.Stub {
if (mEnableThread != null && mEnableThread.isAlive()) {
return false;
}
+
setBluetoothState(BluetoothAdapter.STATE_TURNING_OFF);
- mHandler.removeMessages(MESSAGE_REGISTER_SDP_RECORDS);
+
+ if (mAdapterSdpHandles != null) removeReservedServiceRecordsNative(mAdapterSdpHandles);
setBluetoothTetheringNative(false, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
// Allow 3 seconds for profiles to gracefully disconnect
@@ -516,43 +519,6 @@ public class BluetoothService extends IBluetooth.Stub {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case MESSAGE_REGISTER_SDP_RECORDS:
- if (!isEnabledInternal()) {
- return;
- }
- // SystemService.start() forks sdptool to register service
- // records. It can fail to register some records if it is
- // forked multiple times in a row, probably because there is
- // some race in sdptool or bluez when operated in parallel.
- // As a workaround, delay 500ms between each fork of sdptool.
- // TODO: Don't fork sdptool in order to register service
- // records, use a DBUS call instead.
- switch (msg.arg1) {
- case 1:
- Log.d(TAG, "Registering hfag record");
- SystemService.start("hfag");
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 2, -1), 500);
- break;
- case 2:
- Log.d(TAG, "Registering hsag record");
- SystemService.start("hsag");
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 3, -1), 500);
- break;
- case 3:
- Log.d(TAG, "Registering pbap record");
- SystemService.start("pbap");
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 500);
-
- break;
- case 4:
- Log.d(TAG, "Registering opush record");
- SystemService.start("opush");
- break;
- }
- break;
case MESSAGE_FINISH_DISABLE:
finishDisable(msg.arg1 != 0);
break;
@@ -625,23 +591,40 @@ public class BluetoothService extends IBluetooth.Stub {
if (mSaveSetting) {
persistBluetoothOnSetting(true);
}
- mIsDiscovering = false;
- mBondState.readAutoPairingData();
- mBondState.loadBondState();
- initProfileState();
-
//Register SDP records.
if (mContext.getResources().
getBoolean(com.android.internal.R.bool.config_voice_capable)) {
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 1, -1), 3000);
+ int[] uuids = {
+ BluetoothUuid.getServiceIdentifierFromParcelUuid(
+ BluetoothUuid.Handsfree_AG),
+ BluetoothUuid.getServiceIdentifierFromParcelUuid(
+ BluetoothUuid.HSP_AG),
+ BluetoothUuid.getServiceIdentifierFromParcelUuid(
+ BluetoothUuid.PBAP_PSE),
+ BluetoothUuid.getServiceIdentifierFromParcelUuid(
+ BluetoothUuid.ObexObjectPush),
+ };
+ mAdapterSdpUuids = uuids;
+
} else {
- // Register only OPP.
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 3000);
+ int[] uuids = {
+ BluetoothUuid.getServiceIdentifierFromParcelUuid(
+ BluetoothUuid.HSP_AG),
+ BluetoothUuid.getServiceIdentifierFromParcelUuid(
+ BluetoothUuid.PBAP_PSE),
+ BluetoothUuid.getServiceIdentifierFromParcelUuid(
+ BluetoothUuid.ObexObjectPush),
+ };
+ mAdapterSdpUuids = uuids;
}
+
+ mAdapterSdpHandles = addReservedServiceRecordsNative(mAdapterSdpUuids);
setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
+ mIsDiscovering = false;
+ mBondState.readAutoPairingData();
+ mBondState.loadBondState();
+ initProfileState();
// Log bluetooth on to battery stats.
long ident = Binder.clearCallingIdentity();
@@ -2908,4 +2891,7 @@ public class BluetoothService extends IBluetooth.Stub {
private native boolean setBluetoothTetheringNative(boolean value, String nap, String bridge);
private native boolean connectPanDeviceNative(String path, String srcRole, String dstRole);
private native boolean disconnectPanDeviceNative(String path);
+
+ private native int[] addReservedServiceRecordsNative(int[] uuuids);
+ private native boolean removeReservedServiceRecordsNative(int[] handles);
}
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 848b8f5..cd4d029 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -928,6 +928,79 @@ static jboolean discoverServicesNative(JNIEnv *env, jobject object,
return JNI_FALSE;
}
+static jintArray extract_handles(JNIEnv *env, DBusMessage *reply) {
+#ifdef HAVE_BLUETOOTH
+ jint *handles;
+ jintArray handleArray = NULL;
+ int len;
+
+ DBusError err;
+ dbus_error_init(&err);
+
+ if (dbus_message_get_args(reply, &err,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &handles, &len,
+ DBUS_TYPE_INVALID)) {
+ handleArray = env->NewIntArray(len);
+ if (handleArray) {
+ env->SetIntArrayRegion(handleArray, 0, len, handles);
+ } else {
+ LOGE("Null array in extract_handles");
+ }
+ } else {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ }
+ return handleArray;
+#endif
+ return NULL;
+}
+
+static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
+ jintArray uuids) {
+ LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+ DBusMessage *reply = NULL;
+
+ native_data_t *nat = get_native_data(env, object);
+
+ jint* svc_classes = env->GetIntArrayElements(uuids, NULL);
+ if (!svc_classes) return NULL;
+
+ int len = env->GetArrayLength(uuids);
+ reply = dbus_func_args(env, nat->conn,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "AddReservedServiceRecords",
+ DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
+ &svc_classes, len, DBUS_TYPE_INVALID);
+ env->ReleaseIntArrayElements(uuids, svc_classes, 0);
+ return reply ? extract_handles(env, reply) : NULL;
+
+#endif
+ return NULL;
+}
+
+static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
+ jintArray handles) {
+ LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+ native_data_t *nat = get_native_data(env, object);
+ jint *values = env->GetIntArrayElements(handles, NULL);
+ DBusMessage *msg = NULL;
+ DBusMessage *reply = NULL;
+ if (values == NULL) return JNI_FALSE;
+
+ jsize len = env->GetArrayLength(handles);
+
+ reply = dbus_func_args(env, nat->conn,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE, "RemoveReservedServiceRecords",
+ DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
+ &values, len, DBUS_TYPE_INVALID);
+ env->ReleaseIntArrayElements(handles, values, NULL);
+ return reply ? JNI_TRUE : JNI_FALSE;
+#endif
+ return JNI_FALSE;
+}
+
static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
LOGV(__FUNCTION__);
@@ -1193,6 +1266,8 @@ static JNINativeMethod sMethods[] = {
{"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
{"addRfcommServiceRecordNative", "(Ljava/lang/String;JJS)I", (void *)addRfcommServiceRecordNative},
{"removeServiceRecordNative", "(I)Z", (void *)removeServiceRecordNative},
+ {"addReservedServiceRecordsNative", "([I)[I", (void *) addReservedServiceRecordsNative},
+ {"removeReservedServiceRecordsNative", "([I)Z", (void *) removeReservedServiceRecordsNative},
{"setLinkTimeoutNative", "(Ljava/lang/String;I)Z", (void *)setLinkTimeoutNative},
// HID functions
{"connectInputDeviceNative", "(Ljava/lang/String;)Z", (void *)connectInputDeviceNative},