diff options
author | Jaikumar Ganesh <jaikumar@google.com> | 2010-12-13 13:42:42 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-12-13 13:42:42 -0800 |
commit | faaddc632f01ed148dfe1dd9c38f69524ab099e9 (patch) | |
tree | f02f383fd7ec6f1940c71ef98311ccf863a856d1 | |
parent | a60f00ffec251a13544973f43bf10df2b3e90011 (diff) | |
parent | 84690c88f37f395094147d27ace8319a2803a522 (diff) | |
download | frameworks_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.java | 19 | ||||
-rw-r--r-- | core/java/android/server/BluetoothEventLoop.java | 2 | ||||
-rw-r--r-- | core/java/android/server/BluetoothService.java | 92 | ||||
-rw-r--r-- | core/jni/android_server_BluetoothService.cpp | 75 |
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}, |