Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7719af3 authored by Android (Google) Code Review's avatar Android (Google) Code Review
Browse files

Merge change 26217 into eclair

* changes:
  Cache the remote device's service channel.
parents 5222a957 10eac971
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -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;
        }
        }
+5 −2
Original line number Original line Diff line number Diff line
@@ -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")) {
@@ -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);
    }
    }
+51 −6
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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 {
@@ -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();
    }
    }
@@ -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.
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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);

}
}