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

Commit 0a78da05 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by android-build-merger
Browse files

Merge "Bluetooth LE Advertising minor improvements" am: 3d843624 am: 821523d8 am: bb531074

am: fe0638ff

Change-Id: I4f30951d19f52b040924706a270671562245a802
parents 5dbf82ed fe0638ff
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();