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

Commit 4d3f23e4 authored by Subramanian Srinivasan's avatar Subramanian Srinivasan Committed by Bruno Martins
Browse files

Enhanced Attribute protocol support

GATT client and server SDK APIs support for Enhanced
Attribute protocol.

CRs-Fixed: 2803585
Change-Id: I900e8829866323f57b9b5d9bcf93601e5f10a80e
parent d24d25db
Loading
Loading
Loading
Loading
+43 −1
Original line number Diff line number Diff line
@@ -2355,6 +2355,48 @@ public final class BluetoothDevice implements Parcelable {
    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
            BluetoothGattCallback callback, int transport,
            boolean opportunistic, int phy, Handler handler) {
        return connectGatt(context, autoConnect, callback, transport, opportunistic,
                phy, handler, false);
    }

    /**
     * Connect to GATT Server hosted by this device. Caller acts as GATT client.
     * The callback is used to deliver results to Caller, such as connection status as well
     * as any further GATT client operations.
     * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
     * GATT client operations.
     *
     * @param callback GATT callback handler that will receive asynchronous callbacks.
     * @param autoConnect Whether to directly connect to the remote device (false) or to
     * automatically connect as soon as the remote device becomes available (true).
     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
     * BluetoothDevice#TRANSPORT_LE}
     * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
     * does not hold a GATT connection. It automatically disconnects when no other GATT connections
     * are active for the remote device.
     * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
     * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
     * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
     * is set to true.
     * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
     * an un-specified background thread.
     * @param eattSupport specifies whether client app needs EATT channel for client operations.
     * If both local and remote devices support EATT and local app asks for EATT, GATT client
     * operations will be performed using EATT channel.
     * If either local or remote device doesn't support EATT but local App asks for EATT, GATT
     * client operations will be performed using unenhanced ATT channel.
     *
     * @return A BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client
     * operations.
     *
     * @throws NullPointerException if callback is null
     *
     * @hide
     */
    public BluetoothGatt connectGatt(Context context, boolean autoConnect,
            BluetoothGattCallback callback, int transport, boolean opportunistic,
            int phy, Handler handler, boolean eattSupport) {
        if (callback == null) {
            throw new NullPointerException("callback is null");
        }
@@ -2370,7 +2412,7 @@ public final class BluetoothDevice implements Parcelable {
                return null;
            }
            BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, opportunistic, phy);
            gatt.connect(autoConnect, callback, handler);
            gatt.connect(autoConnect, callback, handler, eattSupport);
            return gatt;
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
+61 −3
Original line number Diff line number Diff line
@@ -799,6 +799,28 @@ public final class BluetoothGatt implements BluetoothProfile {
     * error
     */
    private boolean registerApp(BluetoothGattCallback callback, Handler handler) {
        return registerApp(callback, handler, false);
    }

    /**
     * Register an application callback to start using GATT.
     *
     * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
     * is used to notify success or failure if the function returns true.
     *
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
     *
     * @param callback GATT callback handler that will receive asynchronous callbacks.
     * @param eattSupport specifies whether client app needs EATT channel for client operations.
     * If both local and remote devices support EATT and local app asks for EATT, GATT client
     * operations will be performed using EATT channel.
     * If either local or remote device doesn't support EATT but local App asks for EATT, GATT
     * client operations will be performed using unenhanced ATT channel.
     * @return If true, the callback will be called to notify success or failure, false on immediate
     * error
     * @hide
     */
    private boolean registerApp(BluetoothGattCallback callback, Handler handler, boolean eattSupport) {
        if (DBG) Log.d(TAG, "registerApp()");
        if (mService == null) return false;

@@ -808,7 +830,7 @@ public final class BluetoothGatt implements BluetoothProfile {
        if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);

        try {
            mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
            mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback, eattSupport);
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
            return false;
@@ -859,9 +881,45 @@ public final class BluetoothGatt implements BluetoothProfile {
    @UnsupportedAppUsage
    /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
            Handler handler) {
        return connect(autoConnect, callback, handler, false);
    }

    /**
     * Initiate a connection to a Bluetooth GATT capable device.
     *
     * <p>The connection may not be established right away, but will be
     * completed when the remote device is available. A
     * {@link BluetoothGattCallback#onConnectionStateChange} callback will be
     * invoked when the connection state changes as a result of this function.
     *
     * <p>The autoConnect parameter determines whether to actively connect to
     * the remote device, or rather passively scan and finalize the connection
     * when the remote device is in range/available. Generally, the first ever
     * connection to a device should be direct (autoConnect set to false) and
     * subsequent connections to known devices should be invoked with the
     * autoConnect parameter set to true.
     *
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
     *
     * @param device Remote device to connect to
     * @param autoConnect Whether to directly connect to the remote device (false) or to
     * automatically connect as soon as the remote device becomes available (true).
     * @param eattSupport specifies whether client app needs EATT channel for client operations.
     * If both local and remote devices support EATT and local app asks for EATT, GATT client
     * operations will be performed using EATT channel.
     * If either local or remote device doesn't support EATT but local App asks for EATT, GATT
     * client operations will be performed using unenhanced ATT channel.
     * @return true, if the connection attempt was initiated successfully
     *
     * @hide
     */
    @UnsupportedAppUsage
    /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
            Handler handler, boolean eattSupport) {
        if (DBG) {
            Log.d(TAG,
                    "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
                    "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect
                    + ", eattSupport: " + eattSupport);
        }
        synchronized (mStateLock) {
            if (mConnState != CONN_STATE_IDLE) {
@@ -872,7 +930,7 @@ public final class BluetoothGatt implements BluetoothProfile {

        mAutoConnect = autoConnect;

        if (!registerApp(callback, handler)) {
        if (!registerApp(callback, handler, eattSupport)) {
            synchronized (mStateLock) {
                mConnState = CONN_STATE_IDLE;
            }
+19 −1
Original line number Diff line number Diff line
@@ -443,6 +443,24 @@ public final class BluetoothGattServer implements BluetoothProfile {
     * error
     */
    /*package*/ boolean registerCallback(BluetoothGattServerCallback callback) {
        return registerCallback(callback, false);
    }

    /**
     * Register an application callback to start using GattServer.
     *
     * <p>This is an asynchronous call. The callback is used to notify
     * success or failure if the function returns true.
     *
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
     *
     * @param callback GATT callback handler that will receive asynchronous callbacks.
     * @param eattSupport whether eattSupport is needed for Gatt server
     * @return true, the callback will be called to notify success or failure, false on immediate
     * error
     * @hide
     */
    /*package*/ boolean registerCallback(BluetoothGattServerCallback callback, boolean eattSupport) {
        if (DBG) Log.d(TAG, "registerCallback()");
        if (mService == null) {
            Log.e(TAG, "GATT service not available");
@@ -459,7 +477,7 @@ public final class BluetoothGattServer implements BluetoothProfile {

            mCallback = callback;
            try {
                mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback);
                mService.registerServer(new ParcelUuid(uuid), mBluetoothGattServerCallback, eattSupport);
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
                mCallback = null;
+26 −1
Original line number Diff line number Diff line
@@ -233,6 +233,31 @@ public final class BluetoothManager {
     */
    public BluetoothGattServer openGattServer(Context context,
            BluetoothGattServerCallback callback, int transport) {
        return (openGattServer(context, callback, transport, false));
    }

    /**
     * Open a GATT Server
     * The callback is used to deliver results to Caller, such as connection status as well
     * as the results of any other GATT server operations.
     * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
     * to conduct GATT server operations.
     *
     * @param context App context
     * @param callback GATT server callback handler that will receive asynchronous callbacks.
     * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
     * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
     * BluetoothDevice#TRANSPORT_LE}
     * @param eattSupport specifies whether server app needs EATT channel for server operations.
     * If both local and remote devices support EATT, local app asks for EATT using this API and
     * calls server connect, GATT server operations will be performed using EATT channel.
     * If either local or remote device doesn't support EATT but local App asks for EATT, GATT
     * server operations will be performed using unenhanced ATT channel.
     * @return BluetoothGattServer instance
     * @hide
     */
    public BluetoothGattServer openGattServer(Context context,
            BluetoothGattServerCallback callback, int transport, boolean eattSupport) {
        if (context == null || callback == null) {
            throw new IllegalArgumentException("null parameter: " + context + " " + callback);
        }
@@ -248,7 +273,7 @@ public final class BluetoothManager {
                return null;
            }
            BluetoothGattServer mGattServer = new BluetoothGattServer(iGatt, transport);
            Boolean regStatus = mGattServer.registerCallback(callback);
            Boolean regStatus = mGattServer.registerCallback(callback, eattSupport);
            return regStatus ? mGattServer : null;
        } catch (RemoteException e) {
            Log.e(TAG, "", e);