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

Commit 52feb10e authored by Wei Wang's avatar Wei Wang Committed by Android Git Automerger
Browse files

am fa5f8b4f: am c20ddd45: Merge "Move AdvertiseData length check to...

am fa5f8b4f: am c20ddd45: Merge "Move AdvertiseData length check to BluetoothAdvertiser." into lmp-dev

* commit 'fa5f8b4ff2d67e8344af8ab6adf0171c613ad307':
  Move AdvertiseData length check to BluetoothAdvertiser.
parents 0cf22691 06accb4b
Loading
Loading
Loading
Loading
+1 −50
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ public final class AdvertiseData implements Parcelable {
            @Override
                public AdvertiseData createFromParcel(Parcel in) {
                    Builder builder = new Builder();
                    @SuppressWarnings("unchecked")
                    List<ParcelUuid> uuids = in.readArrayList(ParcelUuid.class.getClassLoader());
                    if (uuids != null) {
                        for (ParcelUuid uuid : uuids) {
@@ -233,12 +234,6 @@ public final class AdvertiseData implements Parcelable {
     * Builder for {@link AdvertiseData}.
     */
    public static final class Builder {
        private static final int MAX_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.
        private static final int FLAGS_FIELD_BYTES = 3;

        @Nullable
        private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
        private int mManufacturerId = -1;
@@ -334,49 +329,5 @@ public final class AdvertiseData implements Parcelable {
                    mServiceData, mManufacturerId, mManufacturerSpecificData,
                    mIncludeTxPowerLevel, mIncludeDeviceName);
        }

        // Compute the size of the advertisement data.
        private int totalBytes() {
            int size = FLAGS_FIELD_BYTES; // flags field is always set.
            if (mServiceUuids != null) {
                int num16BitUuids = 0;
                int num32BitUuids = 0;
                int num128BitUuids = 0;
                for (ParcelUuid uuid : mServiceUuids) {
                    if (BluetoothUuid.is16BitUuid(uuid)) {
                        ++num16BitUuids;
                    } else if (BluetoothUuid.is32BitUuid(uuid)) {
                        ++num32BitUuids;
                    } else {
                        ++num128BitUuids;
                    }
                }
                // 16 bit service uuids are grouped into one field when doing advertising.
                if (num16BitUuids != 0) {
                    size += OVERHEAD_BYTES_PER_FIELD +
                            num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
                }
                // 32 bit service uuids are grouped into one field when doing advertising.
                if (num32BitUuids != 0) {
                    size += OVERHEAD_BYTES_PER_FIELD +
                            num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
                }
                // 128 bit service uuids are grouped into one field when doing advertising.
                if (num128BitUuids != 0) {
                    size += OVERHEAD_BYTES_PER_FIELD +
                            num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
                }
            }
            if (mServiceData != null) {
                size += OVERHEAD_BYTES_PER_FIELD + mServiceData.length;
            }
            if (mManufacturerSpecificData != null) {
                size += OVERHEAD_BYTES_PER_FIELD + mManufacturerSpecificData.length;
            }
            if (mIncludeTxPowerLevel) {
                size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
            }
            return size;
        }
    }
}
+70 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.bluetooth.le;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothManager;
@@ -49,6 +50,14 @@ public final class BluetoothLeAdvertiser {

    private static final String TAG = "BluetoothLeAdvertiser";

    private static final int MAX_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.
    private static final int FLAGS_FIELD_BYTES = 3;
    private static final int MANUFACTURER_SPECIFIC_DATA_LENGTH = 2;
    private static final int SERVICE_DATA_UUID_LENGTH = 2;

    private final IBluetoothManager mBluetoothManager;
    private final Handler mHandler;
    private BluetoothAdapter mBluetoothAdapter;
@@ -101,6 +110,11 @@ public final class BluetoothLeAdvertiser {
        if (callback == null) {
            throw new IllegalArgumentException("callback cannot be null");
        }
        if (totalBytes(advertiseData) > MAX_ADVERTISING_DATA_BYTES ||
                totalBytes(scanResponse) > MAX_ADVERTISING_DATA_BYTES) {
            postCallbackFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
            return;
        }
        if (mLeAdvertisers.containsKey(callback)) {
            postCallbackFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
            return;
@@ -159,6 +173,62 @@ public final class BluetoothLeAdvertiser {
        }
    }

    // Compute the size of the advertise data.
    private int totalBytes(AdvertiseData data) {
        if (data == null) {
            return 0;
        }
        int size = FLAGS_FIELD_BYTES; // flags field is always set.
        if (data.getServiceUuids() != null) {
            int num16BitUuids = 0;
            int num32BitUuids = 0;
            int num128BitUuids = 0;
            for (ParcelUuid uuid : data.getServiceUuids()) {
                if (BluetoothUuid.is16BitUuid(uuid)) {
                    ++num16BitUuids;
                } else if (BluetoothUuid.is32BitUuid(uuid)) {
                    ++num32BitUuids;
                } else {
                    ++num128BitUuids;
                }
            }
            // 16 bit service uuids are grouped into one field when doing advertising.
            if (num16BitUuids != 0) {
                size += OVERHEAD_BYTES_PER_FIELD +
                        num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
            }
            // 32 bit service uuids are grouped into one field when doing advertising.
            if (num32BitUuids != 0) {
                size += OVERHEAD_BYTES_PER_FIELD +
                        num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
            }
            // 128 bit service uuids are grouped into one field when doing advertising.
            if (num128BitUuids != 0) {
                size += OVERHEAD_BYTES_PER_FIELD +
                        num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
            }
        }
        if (data.getServiceDataUuid() != null) {
            size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH
                    + byteLength(data.getServiceData());
        }
        if (data.getManufacturerId() > 0) {
            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH +
                    byteLength(data.getManufacturerSpecificData());
        }
        if (data.getIncludeTxPowerLevel()) {
            size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
        }
        if (data.getIncludeDeviceName() && mBluetoothAdapter.getName() != null) {
            size += OVERHEAD_BYTES_PER_FIELD + mBluetoothAdapter.getName().length();
        }
        return size;
    }

    private int byteLength(byte[] array) {
        return array == null ? 0 : array.length;
    }

    /**
     * Bluetooth GATT interface callbacks for advertising.
     */