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

Commit 82a1cfa4 authored by Wei Wang's avatar Wei Wang Committed by Android (Google) Code Review
Browse files

Merge "Move AdvertiseData length check to BluetoothAdvertiser." into lmp-dev

parents d49d6bf0 0e81ca25
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.
     */