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

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

Merge change Ia4879943 into eclair

* changes:
  Encourage developers to connect RFCOMM by UUID instead of Channel.
parents 35b38cef 16fb88a6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -90,6 +90,7 @@ LOCAL_SRC_FILES += \
	core/java/android/backup/IRestoreSession.aidl \
	core/java/android/backup/IRestoreSession.aidl \
	core/java/android/bluetooth/IBluetooth.aidl \
	core/java/android/bluetooth/IBluetooth.aidl \
	core/java/android/bluetooth/IBluetoothA2dp.aidl \
	core/java/android/bluetooth/IBluetoothA2dp.aidl \
	core/java/android/bluetooth/IBluetoothCallback.aidl \
	core/java/android/bluetooth/IBluetoothHeadset.aidl \
	core/java/android/bluetooth/IBluetoothHeadset.aidl \
	core/java/android/bluetooth/IBluetoothPbap.aidl \
	core/java/android/bluetooth/IBluetoothPbap.aidl \
	core/java/android/content/IContentService.aidl \
	core/java/android/content/IContentService.aidl \
+4 −4
Original line number Original line Diff line number Diff line
@@ -25618,7 +25618,7 @@
 visibility="public"
 visibility="public"
>
>
</method>
</method>
<method name="listenUsingRfcomm"
<method name="listenUsingRfcommWithServiceRecord"
 return="android.bluetooth.BluetoothServerSocket"
 return="android.bluetooth.BluetoothServerSocket"
 abstract="false"
 abstract="false"
 native="false"
 native="false"
@@ -25630,7 +25630,7 @@
>
>
<parameter name="name" type="java.lang.String">
<parameter name="name" type="java.lang.String">
</parameter>
</parameter>
<parameter name="uuid" type="android.os.ParcelUuid">
<parameter name="uuid" type="java.util.UUID">
</parameter>
</parameter>
<exception name="IOException" type="java.io.IOException">
<exception name="IOException" type="java.io.IOException">
</exception>
</exception>
@@ -26804,7 +26804,7 @@
>
>
<implements name="android.os.Parcelable">
<implements name="android.os.Parcelable">
</implements>
</implements>
<method name="createRfcommSocket"
<method name="createRfcommSocketToServiceRecord"
 return="android.bluetooth.BluetoothSocket"
 return="android.bluetooth.BluetoothSocket"
 abstract="false"
 abstract="false"
 native="false"
 native="false"
@@ -26814,7 +26814,7 @@
 deprecated="not deprecated"
 deprecated="not deprecated"
 visibility="public"
 visibility="public"
>
>
<parameter name="channel" type="int">
<parameter name="uuid" type="java.util.UUID">
</parameter>
</parameter>
<exception name="IOException" type="java.io.IOException">
<exception name="IOException" type="java.io.IOException">
</exception>
</exception>
+31 −9
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.Random;
import java.util.Random;
import java.util.Set;
import java.util.Set;
import java.util.UUID;


/**
/**
 * Represents the local Bluetooth adapter.
 * Represents the local Bluetooth adapter.
@@ -564,8 +565,16 @@ public final class BluetoothAdapter {
    }
    }


    /**
    /**
     * Randomly picks RFCOMM channels until none are left.
     * Picks RFCOMM channels until none are left.
     * Avoids reserved channels.
     * Avoids reserved channels.
     * Ideally we would pick random channels, but in the current implementation
     * we start with the channel that is the hash of the UUID, and try every
     * available channel from there. This means that in most cases a given
     * uuid will use the same channel. This is a workaround for a Bluez SDP
     * bug where we are not updating the cache when the channel changes for a
     * uuid.
     * TODO: Fix the Bluez SDP caching bug, and go back to random channel
     * selection
     */
     */
    private static class RfcommChannelPicker {
    private static class RfcommChannelPicker {
        private static final int[] RESERVED_RFCOMM_CHANNELS =  new int[] {
        private static final int[] RESERVED_RFCOMM_CHANNELS =  new int[] {
@@ -579,7 +588,9 @@ public final class BluetoothAdapter {


        private final LinkedList<Integer> mChannels;  // local list of channels left to try
        private final LinkedList<Integer> mChannels;  // local list of channels left to try


        public RfcommChannelPicker() {
        private final UUID mUuid;

        public RfcommChannelPicker(UUID uuid) {
            synchronized (RfcommChannelPicker.class) {
            synchronized (RfcommChannelPicker.class) {
                if (sChannels == null) {
                if (sChannels == null) {
                    // lazy initialization of non-reserved rfcomm channels
                    // lazy initialization of non-reserved rfcomm channels
@@ -594,13 +605,21 @@ public final class BluetoothAdapter {
                }
                }
                mChannels = (LinkedList<Integer>)sChannels.clone();
                mChannels = (LinkedList<Integer>)sChannels.clone();
            }
            }
            mUuid = uuid;
        }
        }
        /* Returns next random channel, or -1 if we're out */
        /* Returns next channel, or -1 if we're out */
        public int nextChannel() {
        public int nextChannel() {
            if (mChannels.size() == 0) {
            int channel = mUuid.hashCode();  // always pick the same channel to try first
                return -1;
            Integer channelInt;
            while (mChannels.size() > 0) {
                channelInt = new Integer(channel);
                if (mChannels.remove(channelInt)) {
                    return channel;
                }
                channel = (channel % BluetoothSocket.MAX_RFCOMM_CHANNEL) + 1;
            }
            }
            return mChannels.remove(sRandom.nextInt(mChannels.size()));

            return -1;
        }
        }
    }
    }


@@ -644,6 +663,8 @@ public final class BluetoothAdapter {
     * can use the same UUID to query our SDP server and discover which channel
     * can use the same UUID to query our SDP server and discover which channel
     * to connect to. This SDP record will be removed when this socket is
     * to connect to. This SDP record will be removed when this socket is
     * closed, or if this application closes unexpectedly.
     * closed, or if this application closes unexpectedly.
     * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to
     * connect to this socket from another device using the same {@link UUID}.
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
     * @param name service name for SDP record
     * @param name service name for SDP record
     * @param uuid uuid for SDP record
     * @param uuid uuid for SDP record
@@ -651,9 +672,9 @@ public final class BluetoothAdapter {
     * @throws IOException on error, for example Bluetooth not available, or
     * @throws IOException on error, for example Bluetooth not available, or
     *                     insufficient permissions, or channel in use.
     *                     insufficient permissions, or channel in use.
     */
     */
    public BluetoothServerSocket listenUsingRfcomm(String name, ParcelUuid uuid)
    public BluetoothServerSocket listenUsingRfcommWithServiceRecord(String name, UUID uuid)
            throws IOException {
            throws IOException {
        RfcommChannelPicker picker = new RfcommChannelPicker();
        RfcommChannelPicker picker = new RfcommChannelPicker(uuid);


        BluetoothServerSocket socket;
        BluetoothServerSocket socket;
        int channel;
        int channel;
@@ -687,7 +708,8 @@ public final class BluetoothAdapter {


        int handle = -1;
        int handle = -1;
        try {
        try {
            handle = mService.addRfcommServiceRecord(name, uuid, channel, new Binder());
            handle = mService.addRfcommServiceRecord(name, new ParcelUuid(uuid), channel,
                    new Binder());
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        if (handle == -1) {
        if (handle == -1) {
            try {
            try {
+51 −17
Original line number Original line Diff line number Diff line
@@ -316,21 +316,16 @@ public final class BluetoothDevice implements Parcelable {
     */
     */
    public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
    public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";



    /**
    private static IBluetooth sService;  /* Guarenteed constant after first object constructed */
     * Lazy initialization. Guaranteed final after first object constructed, or
     * getService() called.
     * TODO: Unify implementation of sService amongst BluetoothFoo API's
     */
    private static IBluetooth sService;


    private final String mAddress;
    private final String mAddress;


    /**
    /*package*/ static IBluetooth getService() {
     * Create a new BluetoothDevice
     * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
     * and is validated in this constructor.
     * @param address valid Bluetooth MAC address
     * @throws RuntimeException Bluetooth is not available on this platform
     * @throws IllegalArgumentException address is invalid
     * @hide
     */
    /*package*/ BluetoothDevice(String address) {
        synchronized (BluetoothDevice.class) {
        synchronized (BluetoothDevice.class) {
            if (sService == null) {
            if (sService == null) {
                IBinder b = ServiceManager.getService(Context.BLUETOOTH_SERVICE);
                IBinder b = ServiceManager.getService(Context.BLUETOOTH_SERVICE);
@@ -340,7 +335,20 @@ public final class BluetoothDevice implements Parcelable {
                sService = IBluetooth.Stub.asInterface(b);
                sService = IBluetooth.Stub.asInterface(b);
            }
            }
        }
        }
        return sService;
    }


    /**
     * Create a new BluetoothDevice
     * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
     * and is validated in this constructor.
     * @param address valid Bluetooth MAC address
     * @throws RuntimeException Bluetooth is not available on this platform
     * @throws IllegalArgumentException address is invalid
     * @hide
     */
    /*package*/ BluetoothDevice(String address) {
        getService();  // ensures sService is initialized
        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
        if (!BluetoothAdapter.checkBluetoothAddress(address)) {
            throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
            throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
        }
        }
@@ -551,7 +559,7 @@ public final class BluetoothDevice implements Parcelable {
      */
      */
     public boolean fetchUuidsWithSdp() {
     public boolean fetchUuidsWithSdp() {
        try {
        try {
            return sService.fetchRemoteUuidsWithSdp(mAddress);
            return sService.fetchRemoteUuids(mAddress, null, null);
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        } catch (RemoteException e) {Log.e(TAG, "", e);}
        return false;
        return false;
    }
    }
@@ -598,7 +606,7 @@ public final class BluetoothDevice implements Parcelable {


    /**
    /**
     * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
     * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
     * outgoing connection to this remote device.
     * outgoing connection to this remote device on given channel.
     * <p>The remote device will be authenticated and communication on this
     * <p>The remote device will be authenticated and communication on this
     * socket will be encrypted.
     * socket will be encrypted.
     * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
     * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
@@ -610,9 +618,34 @@ public final class BluetoothDevice implements Parcelable {
     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
     * @throws IOException on error, for example Bluetooth not available, or
     * @throws IOException on error, for example Bluetooth not available, or
     *                     insufficient permissions
     *                     insufficient permissions
     * @hide
     */
     */
    public BluetoothSocket createRfcommSocket(int channel) throws IOException {
    public BluetoothSocket createRfcommSocket(int channel) throws IOException {
        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel);
        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
                null);
    }

    /**
     * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
     * outgoing connection to this remote device using SDP lookup of uuid.
     * <p>This is designed to be used with {@link
     * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
     * Bluetooth applications.
     * <p>Use {@link BluetoothSocket#connect} to intiate the outgoing
     * connection. This will also perform an SDP lookup of the given uuid to
     * determine which channel to connect to.
     * <p>The remote device will be authenticated and communication on this
     * socket will be encrypted.
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
     *
     * @param uuid service record uuid to lookup RFCOMM channel
     * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
     * @throws IOException on error, for example Bluetooth not available, or
     *                     insufficient permissions
     */
    public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
                new ParcelUuid(uuid));
    }
    }


    /**
    /**
@@ -628,7 +661,8 @@ public final class BluetoothDevice implements Parcelable {
     * @hide
     * @hide
     */
     */
    public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
    public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port);
        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
                null);
    }
    }


    /**
    /**
@@ -640,7 +674,7 @@ public final class BluetoothDevice implements Parcelable {
     * @hide
     * @hide
     */
     */
    public BluetoothSocket createScoSocket() throws IOException {
    public BluetoothSocket createScoSocket() throws IOException {
        return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1);
        return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
    }
    }


    /**
    /**
+6 −6
Original line number Original line Diff line number Diff line
@@ -36,13 +36,13 @@ import java.io.IOException;
 * connection orientated, streaming transport over Bluetooth. It is also known
 * connection orientated, streaming transport over Bluetooth. It is also known
 * as the Serial Port Profile (SPP).
 * as the Serial Port Profile (SPP).
 *
 *
 * <p>Use {@link BluetoothDevice#createRfcommSocket} to create a new {@link
 * <p>Use {@link BluetoothDevice#createRfcommSocketToServiceRecord} to create
 * BluetoothSocket} ready for an outgoing connection to a remote
 * a new {@link BluetoothSocket} ready for an outgoing connection to a remote
 * {@link BluetoothDevice}.
 * {@link BluetoothDevice}.
 *
 *
 * <p>Use {@link BluetoothAdapter#listenUsingRfcomm} to create a listening
 * <p>Use {@link BluetoothAdapter#listenUsingRfcommWithServiceRecord} to
 * {@link BluetoothServerSocket} ready for incoming connections to the local
 * create a listening {@link BluetoothServerSocket} ready for incoming
 * {@link BluetoothAdapter}.
 * connections to the local {@link BluetoothAdapter}.
 *
 *
 * <p>{@link BluetoothSocket} and {@link BluetoothServerSocket} are thread
 * <p>{@link BluetoothSocket} and {@link BluetoothServerSocket} are thread
 * safe. In particular, {@link #close} will always immediately abort ongoing
 * safe. In particular, {@link #close} will always immediately abort ongoing
@@ -68,7 +68,7 @@ public final class BluetoothServerSocket implements Closeable {
     */
     */
    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
    /*package*/ BluetoothServerSocket(int type, boolean auth, boolean encrypt, int port)
            throws IOException {
            throws IOException {
        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port);
        mSocket = new BluetoothSocket(type, -1, auth, encrypt, null, port, null);
    }
    }


    /**
    /**
Loading