Loading core/java/android/bluetooth/BluetoothUuid.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,12 @@ public final class BluetoothUuid { * @param uuid * @param uuid */ */ public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) { public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) { if ((uuidArray == null || uuidArray.length == 0) && uuid == null) return true; if (uuidArray == null) return false; for (ParcelUuid element: uuidArray) { for (ParcelUuid element: uuidArray) { if (element.equals(uuid)) return true; if (element.equals(uuid)) return true; } } Loading core/java/android/server/BluetoothEventLoop.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -369,6 +369,10 @@ class BluetoothEventLoop { uuid = str.toString(); uuid = str.toString(); } } mBluetoothService.setRemoteDeviceProperty(address, name, uuid); mBluetoothService.setRemoteDeviceProperty(address, name, uuid); // UUIDs have changed, query remote service channel and update cache. mBluetoothService.updateDeviceServiceChannelCache(address); mBluetoothService.sendUuidIntent(address); mBluetoothService.sendUuidIntent(address); } else if (name.equals("Paired")) { } else if (name.equals("Paired")) { if (propValues[1].equals("true")) { if (propValues[1].equals("true")) { Loading Loading @@ -537,8 +541,7 @@ class BluetoothEventLoop { String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath); String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath); // We don't parse the xml here, instead just query Bluez for the properties. // We don't parse the xml here, instead just query Bluez for the properties. if (result) { if (result) { String[] properties = mBluetoothService.getRemoteDeviceProperties(address); mBluetoothService.updateRemoteDevicePropertiesCache(address); mBluetoothService.addRemoteDeviceProperties(address, properties); } } mBluetoothService.sendUuidIntent(address); mBluetoothService.sendUuidIntent(address); } } Loading core/java/android/server/BluetoothService.java +51 −6 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetooth; import android.bluetooth.IBluetooth; import android.bluetooth.ParcelUuid; import android.bluetooth.ParcelUuid; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; Loading Loading @@ -85,6 +86,7 @@ public class BluetoothService extends IBluetooth.Stub { private final Map<String, String> mAdapterProperties; private final Map<String, String> mAdapterProperties; private final HashMap <String, Map<String, String>> mDeviceProperties; private final HashMap <String, Map<String, String>> mDeviceProperties; private final HashMap <String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache; private final ArrayList <String> mUuidIntentTracker; private final ArrayList <String> mUuidIntentTracker; static { static { Loading @@ -111,6 +113,8 @@ public class BluetoothService extends IBluetooth.Stub { mIsDiscovering = false; mIsDiscovering = false; mAdapterProperties = new HashMap<String, String>(); mAdapterProperties = new HashMap<String, String>(); mDeviceProperties = new HashMap<String, Map<String,String>>(); mDeviceProperties = new HashMap<String, Map<String,String>>(); mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>(); mUuidIntentTracker = new ArrayList<String>(); mUuidIntentTracker = new ArrayList<String>(); registerForAirplaneMode(); registerForAirplaneMode(); } } Loading Loading @@ -880,16 +884,22 @@ public class BluetoothService extends IBluetooth.Stub { // Query for remote device properties, again. // Query for remote device properties, again. // We will need to reload the cache when we switch Bluetooth on / off // We will need to reload the cache when we switch Bluetooth on / off // or if we crash. // or if we crash. String[] propValues = getRemoteDeviceProperties(address); if (updateRemoteDevicePropertiesCache(address)) if (propValues != null) { addRemoteDeviceProperties(address, propValues); return getRemoteDeviceProperty(address, property); return getRemoteDeviceProperty(address, property); } } } Log.e(TAG, "getRemoteDeviceProperty: " + property + "not present:" + address); Log.e(TAG, "getRemoteDeviceProperty: " + property + "not present:" + address); return null; return null; } } /* package */ synchronized boolean updateRemoteDevicePropertiesCache(String address) { String[] propValues = getRemoteDeviceProperties(address); if (propValues != null) { addRemoteDeviceProperties(address, propValues); return true; } return false; } /* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) { /* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) { /* /* * We get a DeviceFound signal every time RSSI changes or name changes. * We get a DeviceFound signal every time RSSI changes or name changes. Loading Loading @@ -924,6 +934,10 @@ public class BluetoothService extends IBluetooth.Stub { propertyValues.put(name, newValue); propertyValues.put(name, newValue); } } mDeviceProperties.put(address, propertyValues); mDeviceProperties.put(address, propertyValues); // We have added a new remote device or updated its properties. // Also update the serviceChannel cache. updateDeviceServiceChannelCache(address); } } /* package */ void removeRemoteDeviceProperties(String address) { /* package */ void removeRemoteDeviceProperties(String address) { Loading Loading @@ -1066,14 +1080,23 @@ public class BluetoothService extends IBluetooth.Stub { * @param uuid ParcelUuid of the service attribute * @param uuid ParcelUuid of the service attribute * * * @return rfcomm channel associated with the service attribute * @return rfcomm channel associated with the service attribute * -1 on error */ */ public int getRemoteServiceChannel(String address, ParcelUuid uuid) { public int getRemoteServiceChannel(String address, ParcelUuid uuid) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); if (!BluetoothAdapter.checkBluetoothAddress(address)) { if (!BluetoothAdapter.checkBluetoothAddress(address)) { return BluetoothDevice.ERROR; return BluetoothDevice.ERROR; } } return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(), // Check if we are recovering from a crash. 0x0004); if (mDeviceProperties.isEmpty()) { if (!updateRemoteDevicePropertiesCache(address)) return -1; } Map<ParcelUuid, Integer> value = mDeviceServiceChannelCache.get(address); if (value != null && value.containsKey(uuid)) return value.get(uuid); return -1; } } public synchronized boolean setPin(String address, byte[] pin) { public synchronized boolean setPin(String address, byte[] pin) { Loading Loading @@ -1152,6 +1175,27 @@ public class BluetoothService extends IBluetooth.Stub { return cancelPairingUserInputNative(address, data.intValue()); return cancelPairingUserInputNative(address, data.intValue()); } } public void updateDeviceServiceChannelCache(String address) { ParcelUuid[] deviceUuids = getRemoteUuids(address); // We are storing the rfcomm channel numbers only for the uuids // we are interested in. int channel; ParcelUuid[] interestedUuids = {BluetoothUuid.Handsfree, BluetoothUuid.HSP, BluetoothUuid.ObexObjectPush}; Map <ParcelUuid, Integer> value = new HashMap<ParcelUuid, Integer>(); for (ParcelUuid uuid: interestedUuids) { if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) { channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(), 0x0004); value.put(uuid, channel); } } mDeviceServiceChannelCache.put(address, value); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { Loading Loading @@ -1366,4 +1410,5 @@ public class BluetoothService extends IBluetooth.Stub { private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value); private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value); private native boolean createDeviceNative(String address); private native boolean createDeviceNative(String address); private native boolean discoverServicesNative(String objectPath, String pattern); private native boolean discoverServicesNative(String objectPath, String pattern); } } Loading
core/java/android/bluetooth/BluetoothUuid.java +6 −0 Original line number Original line Diff line number Diff line Loading @@ -83,6 +83,12 @@ public final class BluetoothUuid { * @param uuid * @param uuid */ */ public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) { public static boolean isUuidPresent(ParcelUuid[] uuidArray, ParcelUuid uuid) { if ((uuidArray == null || uuidArray.length == 0) && uuid == null) return true; if (uuidArray == null) return false; for (ParcelUuid element: uuidArray) { for (ParcelUuid element: uuidArray) { if (element.equals(uuid)) return true; if (element.equals(uuid)) return true; } } Loading
core/java/android/server/BluetoothEventLoop.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -369,6 +369,10 @@ class BluetoothEventLoop { uuid = str.toString(); uuid = str.toString(); } } mBluetoothService.setRemoteDeviceProperty(address, name, uuid); mBluetoothService.setRemoteDeviceProperty(address, name, uuid); // UUIDs have changed, query remote service channel and update cache. mBluetoothService.updateDeviceServiceChannelCache(address); mBluetoothService.sendUuidIntent(address); mBluetoothService.sendUuidIntent(address); } else if (name.equals("Paired")) { } else if (name.equals("Paired")) { if (propValues[1].equals("true")) { if (propValues[1].equals("true")) { Loading Loading @@ -537,8 +541,7 @@ class BluetoothEventLoop { String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath); String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath); // We don't parse the xml here, instead just query Bluez for the properties. // We don't parse the xml here, instead just query Bluez for the properties. if (result) { if (result) { String[] properties = mBluetoothService.getRemoteDeviceProperties(address); mBluetoothService.updateRemoteDevicePropertiesCache(address); mBluetoothService.addRemoteDeviceProperties(address, properties); } } mBluetoothService.sendUuidIntent(address); mBluetoothService.sendUuidIntent(address); } } Loading
core/java/android/server/BluetoothService.java +51 −6 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetooth; import android.bluetooth.IBluetooth; import android.bluetooth.ParcelUuid; import android.bluetooth.ParcelUuid; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; Loading Loading @@ -85,6 +86,7 @@ public class BluetoothService extends IBluetooth.Stub { private final Map<String, String> mAdapterProperties; private final Map<String, String> mAdapterProperties; private final HashMap <String, Map<String, String>> mDeviceProperties; private final HashMap <String, Map<String, String>> mDeviceProperties; private final HashMap <String, Map<ParcelUuid, Integer>> mDeviceServiceChannelCache; private final ArrayList <String> mUuidIntentTracker; private final ArrayList <String> mUuidIntentTracker; static { static { Loading @@ -111,6 +113,8 @@ public class BluetoothService extends IBluetooth.Stub { mIsDiscovering = false; mIsDiscovering = false; mAdapterProperties = new HashMap<String, String>(); mAdapterProperties = new HashMap<String, String>(); mDeviceProperties = new HashMap<String, Map<String,String>>(); mDeviceProperties = new HashMap<String, Map<String,String>>(); mDeviceServiceChannelCache = new HashMap<String, Map<ParcelUuid, Integer>>(); mUuidIntentTracker = new ArrayList<String>(); mUuidIntentTracker = new ArrayList<String>(); registerForAirplaneMode(); registerForAirplaneMode(); } } Loading Loading @@ -880,16 +884,22 @@ public class BluetoothService extends IBluetooth.Stub { // Query for remote device properties, again. // Query for remote device properties, again. // We will need to reload the cache when we switch Bluetooth on / off // We will need to reload the cache when we switch Bluetooth on / off // or if we crash. // or if we crash. String[] propValues = getRemoteDeviceProperties(address); if (updateRemoteDevicePropertiesCache(address)) if (propValues != null) { addRemoteDeviceProperties(address, propValues); return getRemoteDeviceProperty(address, property); return getRemoteDeviceProperty(address, property); } } } Log.e(TAG, "getRemoteDeviceProperty: " + property + "not present:" + address); Log.e(TAG, "getRemoteDeviceProperty: " + property + "not present:" + address); return null; return null; } } /* package */ synchronized boolean updateRemoteDevicePropertiesCache(String address) { String[] propValues = getRemoteDeviceProperties(address); if (propValues != null) { addRemoteDeviceProperties(address, propValues); return true; } return false; } /* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) { /* package */ synchronized void addRemoteDeviceProperties(String address, String[] properties) { /* /* * We get a DeviceFound signal every time RSSI changes or name changes. * We get a DeviceFound signal every time RSSI changes or name changes. Loading Loading @@ -924,6 +934,10 @@ public class BluetoothService extends IBluetooth.Stub { propertyValues.put(name, newValue); propertyValues.put(name, newValue); } } mDeviceProperties.put(address, propertyValues); mDeviceProperties.put(address, propertyValues); // We have added a new remote device or updated its properties. // Also update the serviceChannel cache. updateDeviceServiceChannelCache(address); } } /* package */ void removeRemoteDeviceProperties(String address) { /* package */ void removeRemoteDeviceProperties(String address) { Loading Loading @@ -1066,14 +1080,23 @@ public class BluetoothService extends IBluetooth.Stub { * @param uuid ParcelUuid of the service attribute * @param uuid ParcelUuid of the service attribute * * * @return rfcomm channel associated with the service attribute * @return rfcomm channel associated with the service attribute * -1 on error */ */ public int getRemoteServiceChannel(String address, ParcelUuid uuid) { public int getRemoteServiceChannel(String address, ParcelUuid uuid) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); if (!BluetoothAdapter.checkBluetoothAddress(address)) { if (!BluetoothAdapter.checkBluetoothAddress(address)) { return BluetoothDevice.ERROR; return BluetoothDevice.ERROR; } } return getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(), // Check if we are recovering from a crash. 0x0004); if (mDeviceProperties.isEmpty()) { if (!updateRemoteDevicePropertiesCache(address)) return -1; } Map<ParcelUuid, Integer> value = mDeviceServiceChannelCache.get(address); if (value != null && value.containsKey(uuid)) return value.get(uuid); return -1; } } public synchronized boolean setPin(String address, byte[] pin) { public synchronized boolean setPin(String address, byte[] pin) { Loading Loading @@ -1152,6 +1175,27 @@ public class BluetoothService extends IBluetooth.Stub { return cancelPairingUserInputNative(address, data.intValue()); return cancelPairingUserInputNative(address, data.intValue()); } } public void updateDeviceServiceChannelCache(String address) { ParcelUuid[] deviceUuids = getRemoteUuids(address); // We are storing the rfcomm channel numbers only for the uuids // we are interested in. int channel; ParcelUuid[] interestedUuids = {BluetoothUuid.Handsfree, BluetoothUuid.HSP, BluetoothUuid.ObexObjectPush}; Map <ParcelUuid, Integer> value = new HashMap<ParcelUuid, Integer>(); for (ParcelUuid uuid: interestedUuids) { if (BluetoothUuid.isUuidPresent(deviceUuids, uuid)) { channel = getDeviceServiceChannelNative(getObjectPathFromAddress(address), uuid.toString(), 0x0004); value.put(uuid, channel); } } mDeviceServiceChannelCache.put(address, value); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { Loading Loading @@ -1366,4 +1410,5 @@ public class BluetoothService extends IBluetooth.Stub { private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value); private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value); private native boolean createDeviceNative(String address); private native boolean createDeviceNative(String address); private native boolean discoverServicesNative(String objectPath, String pattern); private native boolean discoverServicesNative(String objectPath, String pattern); } }