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

Commit c4844e9a authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Gerrit Code Review
Browse files

Merge "Bluetooth LE Advertising minor improvements"

parents a7f399ae 76741757
Loading
Loading
Loading
Loading
+30 −8
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.bluetooth.le;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.le.IAdvertisingSetCallback;
@@ -57,11 +58,12 @@ public final class AdvertisingSet {

    /**
     * Enables Advertising. This method returns immediately, the operation status is
     * delivered
     * through {@code callback.onAdvertisingEnabled()}.
     * delivered through {@code callback.onAdvertisingEnabled()}.
     * <p>
     * Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
     *
     * @param enable whether the advertising should be enabled (true), or disabled (false)
     * @param timeoutMillis duration for which that advertising set is enabled.
     */
    public void enableAdvertising(boolean enable, int timeout) {
        try {
@@ -77,10 +79,16 @@ public final class AdvertisingSet {
     * delivered through {@code callback.onAdvertisingDataSet()}.
     * <p>
     * Advertising data must be empty if non-legacy scannable advertising is used.
     *
     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
     *                     advertisement is connectable, three bytes will be added for flags. If the
     *                     update takes place when the advertising set is enabled, the data can be
     *                     maximum 251 bytes long.
     */
    public void setAdvertisingData(AdvertiseData data) {
    public void setAdvertisingData(AdvertiseData advertiseData) {
        try {
            gatt.setAdvertisingData(this.advertiserId, data);
            gatt.setAdvertisingData(this.advertiserId, advertiseData);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
@@ -90,10 +98,15 @@ public final class AdvertisingSet {
     * Set/update scan response data. Make sure that data doesn't exceed the size limit for
     * specified AdvertisingSetParameters. This method returns immediately, the operation status
     * is delivered through {@code callback.onScanResponseDataSet()}.
     *
     * @param scanResponse Scan response associated with the advertisement data. Size must not
     *                     exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
     *                     update takes place when the advertising set is enabled, the data can be
     *                     maximum 251 bytes long.
     */
    public void setScanResponseData(AdvertiseData data) {
    public void setScanResponseData(AdvertiseData scanResponse) {
        try {
            gatt.setScanResponseData(this.advertiserId, data);
            gatt.setScanResponseData(this.advertiserId, scanResponse);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
@@ -103,6 +116,8 @@ public final class AdvertisingSet {
     * Update advertising parameters associated with this AdvertisingSet. Must be called when
     * advertising is not active. This method returns immediately, the operation status is delivered
     * through {@code callback.onAdvertisingParametersUpdated}.
     *
     * @param parameters advertising set parameters.
     */
    public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
        try {
@@ -130,10 +145,15 @@ public final class AdvertisingSet {
     * or after advertising was started with periodic advertising data set. This method returns
     * immediately, the operation status is delivered through
     * {@code callback.onPeriodicAdvertisingDataSet()}.
     *
     * @param periodicData Periodic advertising data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
     *                     update takes place when the periodic advertising is enabled for this set,
     *                     the data can be maximum 251 bytes long.
     */
    public void setPeriodicAdvertisingData(AdvertiseData data) {
    public void setPeriodicAdvertisingData(AdvertiseData periodicData) {
        try {
            gatt.setPeriodicAdvertisingData(this.advertiserId, data);
            gatt.setPeriodicAdvertisingData(this.advertiserId, periodicData);
        } catch (RemoteException e) {
            Log.e(TAG, "remote exception - ", e);
        }
@@ -142,6 +162,8 @@ public final class AdvertisingSet {
    /**
     * Used to enable/disable periodic advertising. This method returns immediately, the operation
     * status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
     *
     * @param enable whether the periodic advertising should be enabled (true), or disabled (false).
     */
    public void setPeriodicAdvertisingEnable(boolean enable) {
        try {
+34 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.bluetooth.le;

import android.bluetooth.BluetoothAdapter;
import android.os.Parcel;
import android.os.Parcelable;

@@ -317,6 +318,8 @@ public final class AdvertisingSetParameters implements Parcelable {
         *
         * This is used only if legacy mode is not used.
         *
         * Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
         * supported on this device.
         * @param primaryPhy Primary advertising physical channel, can only be
         *            {@link AdvertisingSetParameters#PHY_LE_1M} or
         *            {@link AdvertisingSetParameters#PHY_LE_CODED}.
@@ -335,6 +338,10 @@ public final class AdvertisingSetParameters implements Parcelable {
         *
         * This is used only if legacy mode is not used.
         *
         * Use {@link BluetoothAdapter#isLeCodedPhySupported} and
         * {@link BluetoothAdapter#isLe2MPhySupported} to determine if LE Coded PHY or 2M PHY is
         * supported on this device.
         *
         * @param secondaryPhy Secondary advertising physical channel, can only be
         *            one of {@link AdvertisingSetParameters#PHY_LE_1M},
         *            {@link AdvertisingSetParameters#PHY_LE_2M} or
@@ -393,6 +400,32 @@ public final class AdvertisingSetParameters implements Parcelable {
         * Build the {@link AdvertisingSetParameters} object.
         */
        public AdvertisingSetParameters build() {
            if (isLegacy) {
                if (isAnonymous) {
                    throw new IllegalArgumentException("Legacy advertising can't be anonymous");
                }

                if (connectable == true && scannable == false) {
                    throw new IllegalArgumentException(
                        "Legacy advertisement can't be connectable and non-scannable");
                }

                if (includeTxPower) {
                    throw new IllegalArgumentException(
                        "Legacy advertising can't include TX power level in header");
                }
            } else {
                if (connectable && scannable) {
                    throw new IllegalArgumentException(
                        "Advertising can't be both connectable and scannable");
                }

                if (isAnonymous && connectable) {
                    throw new IllegalArgumentException(
                        "Advertising can't be both connectable and anonymous");
                }
            }

            return new AdvertisingSetParameters(connectable, scannable, isLegacy, isAnonymous,
                                                includeTxPower, primaryPhy,
                                                secondaryPhy, interval, txPowerLevel);
+131 −48
Original line number Diff line number Diff line
@@ -50,7 +50,8 @@ public final class BluetoothLeAdvertiser {

    private static final String TAG = "BluetoothLeAdvertiser";

    private static final int MAX_ADVERTISING_DATA_BYTES = 31;
    private static final int MAX_ADVERTISING_DATA_BYTES = 1650;
    private static final int MAX_LEGACY_ADVERTISING_DATA_BYTES = 31;
    // Each fields need one byte for field length and another byte for field type.
    private static final int OVERHEAD_BYTES_PER_FIELD = 2;
    // Flags field will be set by system.
@@ -116,8 +117,8 @@ public final class BluetoothLeAdvertiser {
                throw new IllegalArgumentException("callback cannot be null");
            }
            boolean isConnectable = settings.isConnectable();
            if (totalBytes(advertiseData, isConnectable) > MAX_ADVERTISING_DATA_BYTES ||
                    totalBytes(scanResponse, false) > MAX_ADVERTISING_DATA_BYTES) {
            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES ||
                    totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
                postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
                return;
            }
@@ -210,10 +211,20 @@ public final class BluetoothLeAdvertiser {
     * {@code callback.onAdvertisingSetStarted()}.
     * <p>
     * @param parameters advertising set parameters.
    * @param advertiseData Advertisement data to be broadcasted.
    * @param scanResponse Scan response associated with the advertisement data.
    * @param periodicData Periodic advertising data.
     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
     *                     advertisement is connectable, three bytes will be added for flags.
     * @param scanResponse Scan response associated with the advertisement data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
     *                     not be started.
     * @param periodicData Periodic advertising data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
     * @param callback Callback for advertising set.
     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
     *                     size, or unsupported advertising PHY is selected, or when attempt to use
     *                     Periodic Advertising feature is made when it's not supported by the
     *                     controller.
     */
    public void startAdvertisingSet(AdvertisingSetParameters parameters,
                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
@@ -229,11 +240,21 @@ public final class BluetoothLeAdvertiser {
     * {@code callback.onAdvertisingSetStarted()}.
     * <p>
     * @param parameters advertising set parameters.
    * @param advertiseData Advertisement data to be broadcasted.
    * @param scanResponse Scan response associated with the advertisement data.
    * @param periodicData Periodic advertising data.
     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
     *                     advertisement is connectable, three bytes will be added for flags.
     * @param scanResponse Scan response associated with the advertisement data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
     *                     not be started.
     * @param periodicData Periodic advertising data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
     * @param callback Callback for advertising set.
     * @param handler thread upon which the callbacks will be invoked.
     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
     *                     size, or unsupported advertising PHY is selected, or when attempt to use
     *                     Periodic Advertising feature is made when it's not supported by the
     *                     controller.
     */
    public void startAdvertisingSet(AdvertisingSetParameters parameters,
                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
@@ -250,11 +271,21 @@ public final class BluetoothLeAdvertiser {
     * {@code callback.onAdvertisingSetStarted()}.
     * <p>
     * @param parameters advertising set parameters.
    * @param advertiseData Advertisement data to be broadcasted.
    * @param scanResponse Scan response associated with the advertisement data.
    * @param periodicData Periodic advertising data.
     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
     *                     advertisement is connectable, three bytes will be added for flags.
     * @param scanResponse Scan response associated with the advertisement data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
     *                     not be started.
     * @param periodicData Periodic advertising data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
     * @param timeoutMillis Advertising time limit. May not exceed 180000
     * @param callback Callback for advertising set.
     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
     *                     size, or unsupported advertising PHY is selected, or when attempt to use
     *                     Periodic Advertising feature is made when it's not supported by the
     *                     controller.
     */
    public void startAdvertisingSet(AdvertisingSetParameters parameters,
                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
@@ -271,12 +302,22 @@ public final class BluetoothLeAdvertiser {
     * {@code callback.onAdvertisingSetStarted()}.
     * <p>
     * @param parameters advertising set parameters.
    * @param advertiseData Advertisement data to be broadcasted.
    * @param scanResponse Scan response associated with the advertisement data.
    * @param periodicData Periodic advertising data.
     * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
     *                     advertisement is connectable, three bytes will be added for flags.
     * @param scanResponse Scan response associated with the advertisement data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
     * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
     *                     not be started.
     * @param periodicData Periodic advertising data. Size must not exceed
     *                     {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
     * @param timeoutMillis Advertising time limit. May not exceed 180000
     * @param callback Callback for advertising set.
     * @param handler thread upon which the callbacks will be invoked.
     * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
     *                     size, or unsupported advertising PHY is selected, or when attempt to use
     *                     Periodic Advertising feature is made when it's not supported by the
     *                     controller.
     */
    public void startAdvertisingSet(AdvertisingSetParameters parameters,
                                    AdvertiseData advertiseData, AdvertiseData scanResponse,
@@ -284,11 +325,53 @@ public final class BluetoothLeAdvertiser {
                                    AdvertiseData periodicData, int timeoutMillis,
                                    AdvertisingSetCallback callback, Handler handler) {
        BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);

        if (callback == null) {
          throw new IllegalArgumentException("callback cannot be null");
        }

        boolean isConnectable = parameters.isConnectable();
        if (parameters.isLegacy()) {
            if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
                throw new IllegalArgumentException("Legacy advertising data too big");
            }

            if (totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
                throw new IllegalArgumentException("Legacy scan response data too big");
            }
        } else {
            boolean supportCodedPhy = mBluetoothAdapter.isLeCodedPhySupported();
            boolean support2MPhy = mBluetoothAdapter.isLe2MPhySupported();
            int pphy = parameters.getPrimaryPhy();
            int sphy = parameters.getSecondaryPhy();
            if (pphy == AdvertisingSetParameters.PHY_LE_CODED && !supportCodedPhy) {
                throw new IllegalArgumentException("Unsupported primary PHY selected");
            }

            if ((sphy == AdvertisingSetParameters.PHY_LE_CODED && !supportCodedPhy)
                || (sphy == AdvertisingSetParameters.PHY_LE_2M && !support2MPhy)) {
                throw new IllegalArgumentException("Unsupported secondary PHY selected");
            }

            int maxData = mBluetoothAdapter.getLeMaximumAdvertisingDataLength();
            if (totalBytes(advertiseData, isConnectable) > maxData) {
                throw new IllegalArgumentException("Advertising data too big");
            }

            if (totalBytes(scanResponse, false) > maxData) {
                throw new IllegalArgumentException("Scan response data too big");
            }

            if (totalBytes(periodicData, false) > maxData) {
                throw new IllegalArgumentException("Periodic advertising data too big");
            }

            boolean supportPeriodic = mBluetoothAdapter.isLePeriodicAdvertisingSupported();
            if (periodicParameters != null && periodicParameters.getEnable() && !supportPeriodic) {
                throw new IllegalArgumentException(
                    "Controller does not support LE Periodic Advertising");
            }
        }

        IBluetoothGatt gatt;
        try {
          gatt = mBluetoothManager.getBluetoothGatt();