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

Commit 6bf513d3 authored by Wei Wang's avatar Wei Wang
Browse files

Revert "Revert "Service data and manufacturer data can be repeated fields.""

This reverts commit 14c797702543bb5ced989565d90abcfa55c7db46.
parent 9aa499ac
Loading
Loading
Loading
Loading
+9 −10
Original line number Original line Diff line number Diff line
@@ -6582,22 +6582,20 @@ package android.bluetooth.le {
    method public int describeContents();
    method public int describeContents();
    method public boolean getIncludeDeviceName();
    method public boolean getIncludeDeviceName();
    method public boolean getIncludeTxPowerLevel();
    method public boolean getIncludeTxPowerLevel();
    method public int getManufacturerId();
    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
    method public byte[] getManufacturerSpecificData();
    method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
    method public byte[] getServiceData();
    method public android.os.ParcelUuid getServiceDataUuid();
    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
    method public void writeToParcel(android.os.Parcel, int);
    method public void writeToParcel(android.os.Parcel, int);
  }
  }
  public static final class AdvertiseData.Builder {
  public static final class AdvertiseData.Builder {
    ctor public AdvertiseData.Builder();
    ctor public AdvertiseData.Builder();
    method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]);
    method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]);
    method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
    method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
    method public android.bluetooth.le.AdvertiseData build();
    method public android.bluetooth.le.AdvertiseData build();
    method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
    method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
    method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
    method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
    method public android.bluetooth.le.AdvertiseData.Builder setManufacturerData(int, byte[]);
    method public android.bluetooth.le.AdvertiseData.Builder setServiceData(android.os.ParcelUuid, byte[]);
  }
  }
  public final class AdvertiseSettings implements android.os.Parcelable {
  public final class AdvertiseSettings implements android.os.Parcelable {
@@ -6658,6 +6656,7 @@ package android.bluetooth.le {
    method public int getManufacturerId();
    method public int getManufacturerId();
    method public byte[] getServiceData();
    method public byte[] getServiceData();
    method public byte[] getServiceDataMask();
    method public byte[] getServiceDataMask();
    method public android.os.ParcelUuid getServiceDataUuid();
    method public android.os.ParcelUuid getServiceUuid();
    method public android.os.ParcelUuid getServiceUuid();
    method public android.os.ParcelUuid getServiceUuidMask();
    method public android.os.ParcelUuid getServiceUuidMask();
    method public boolean matches(android.bluetooth.le.ScanResult);
    method public boolean matches(android.bluetooth.le.ScanResult);
@@ -6681,10 +6680,10 @@ package android.bluetooth.le {
    method public int getAdvertiseFlags();
    method public int getAdvertiseFlags();
    method public byte[] getBytes();
    method public byte[] getBytes();
    method public java.lang.String getDeviceName();
    method public java.lang.String getDeviceName();
    method public int getManufacturerId();
    method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
    method public byte[] getManufacturerSpecificData();
    method public byte[] getManufacturerSpecificData(int);
    method public byte[] getServiceData();
    method public java.util.Map<android.os.ParcelUuid, byte[]> getServiceData();
    method public android.os.ParcelUuid getServiceDataUuid();
    method public byte[] getServiceData(android.os.ParcelUuid);
    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
    method public java.util.List<android.os.ParcelUuid> getServiceUuids();
    method public int getTxPowerLevel();
    method public int getTxPowerLevel();
  }
  }
+71 −91
Original line number Original line Diff line number Diff line
@@ -17,14 +17,15 @@
package android.bluetooth.le;
package android.bluetooth.le;


import android.annotation.Nullable;
import android.annotation.Nullable;
import android.bluetooth.BluetoothUuid;
import android.os.Parcel;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.ParcelUuid;
import android.os.Parcelable;
import android.os.Parcelable;
import android.util.ArrayMap;
import android.util.SparseArray;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Objects;


/**
/**
@@ -42,27 +43,18 @@ public final class AdvertiseData implements Parcelable {
    @Nullable
    @Nullable
    private final List<ParcelUuid> mServiceUuids;
    private final List<ParcelUuid> mServiceUuids;


    private final int mManufacturerId;
    private final SparseArray<byte[]> mManufacturerSpecificData;
    @Nullable
    private final Map<ParcelUuid, byte[]> mServiceData;
    private final byte[] mManufacturerSpecificData;

    @Nullable
    private final ParcelUuid mServiceDataUuid;
    @Nullable
    private final byte[] mServiceData;

    private final boolean mIncludeTxPowerLevel;
    private final boolean mIncludeTxPowerLevel;
    private final boolean mIncludeDeviceName;
    private final boolean mIncludeDeviceName;


    private AdvertiseData(List<ParcelUuid> serviceUuids,
    private AdvertiseData(List<ParcelUuid> serviceUuids,
            ParcelUuid serviceDataUuid, byte[] serviceData,
            SparseArray<byte[]> manufacturerData,
            int manufacturerId,
            Map<ParcelUuid, byte[]> serviceData,
            byte[] manufacturerSpecificData, boolean includeTxPowerLevel,
            boolean includeTxPowerLevel,
            boolean includeDeviceName) {
            boolean includeDeviceName) {
        mServiceUuids = serviceUuids;
        mServiceUuids = serviceUuids;
        mManufacturerId = manufacturerId;
        mManufacturerSpecificData = manufacturerData;
        mManufacturerSpecificData = manufacturerSpecificData;
        mServiceDataUuid = serviceDataUuid;
        mServiceData = serviceData;
        mServiceData = serviceData;
        mIncludeTxPowerLevel = includeTxPowerLevel;
        mIncludeTxPowerLevel = includeTxPowerLevel;
        mIncludeDeviceName = includeDeviceName;
        mIncludeDeviceName = includeDeviceName;
@@ -77,32 +69,17 @@ public final class AdvertiseData implements Parcelable {
    }
    }


    /**
    /**
     * Returns the manufacturer identifier, which is a non-negative number assigned by Bluetooth
     * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
     * SIG.
     * manufacturer id is a non-negative number assigned by Bluetooth SIG.
     */
     */
    public int getManufacturerId() {
    public SparseArray<byte[]> getManufacturerSpecificData() {
        return mManufacturerId;
    }

    /**
     * Returns the manufacturer specific data which is the content of manufacturer specific data
     * field. The first 2 bytes of the data contain the company id.
     */
    public byte[] getManufacturerSpecificData() {
        return mManufacturerSpecificData;
        return mManufacturerSpecificData;
    }
    }


    /**
    /**
     * Returns a 16-bit UUID of the service that the service data is associated with.
     * Returns a map of 16-bit UUID and its corresponding service data.
     */
     */
    public ParcelUuid getServiceDataUuid() {
    public Map<ParcelUuid, byte[]> getServiceData() {
        return mServiceDataUuid;
    }

    /**
     * Returns service data.
     */
    public byte[] getServiceData() {
        return mServiceData;
        return mServiceData;
    }
    }


@@ -125,8 +102,8 @@ public final class AdvertiseData implements Parcelable {
     */
     */
    @Override
    @Override
    public int hashCode() {
    public int hashCode() {
        return Objects.hash(mServiceUuids, mManufacturerId, mManufacturerSpecificData,
        return Objects.hash(mServiceUuids, mManufacturerSpecificData, mServiceData,
                mServiceDataUuid, mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel);
                mIncludeDeviceName, mIncludeTxPowerLevel);
    }
    }


    /**
    /**
@@ -142,20 +119,17 @@ public final class AdvertiseData implements Parcelable {
        }
        }
        AdvertiseData other = (AdvertiseData) obj;
        AdvertiseData other = (AdvertiseData) obj;
        return Objects.equals(mServiceUuids, other.mServiceUuids) &&
        return Objects.equals(mServiceUuids, other.mServiceUuids) &&
                mManufacturerId == other.mManufacturerId &&
                Utils.equals(mManufacturerSpecificData, other.mManufacturerSpecificData) &&
                Objects.deepEquals(mManufacturerSpecificData, other.mManufacturerSpecificData) &&
                Utils.equals(mServiceData, other.mServiceData) &&
                Objects.equals(mServiceDataUuid, other.mServiceDataUuid) &&
                Objects.deepEquals(mServiceData, other.mServiceData) &&
                        mIncludeDeviceName == other.mIncludeDeviceName &&
                        mIncludeDeviceName == other.mIncludeDeviceName &&
                        mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
                        mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
    }
    }


    @Override
    @Override
    public String toString() {
    public String toString() {
        return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerId="
        return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerSpecificData="
                + mManufacturerId + ", mManufacturerSpecificData="
                + Utils.toString(mManufacturerSpecificData) + ", mServiceData="
                + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid="
                + Utils.toString(mServiceData)
                + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData)
                + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
                + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
                + mIncludeDeviceName + "]";
                + mIncludeDeviceName + "]";
    }
    }
@@ -169,21 +143,30 @@ public final class AdvertiseData implements Parcelable {
    public void writeToParcel(Parcel dest, int flags) {
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeList(mServiceUuids);
        dest.writeList(mServiceUuids);


        dest.writeInt(mManufacturerId);
        // mManufacturerSpecificData could not be null.
        if (mManufacturerSpecificData == null) {
        dest.writeInt(mManufacturerSpecificData.size());
        for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
            dest.writeInt(mManufacturerSpecificData.keyAt(i));
            byte[] data = mManufacturerSpecificData.valueAt(i);
            if (data == null) {
                dest.writeInt(0);
                dest.writeInt(0);
            } else {
            } else {
                dest.writeInt(1);
                dest.writeInt(1);
            dest.writeInt(mManufacturerSpecificData.length);
                dest.writeInt(data.length);
            dest.writeByteArray(mManufacturerSpecificData);
                dest.writeByteArray(data);
            }
        }
        }
        dest.writeParcelable(mServiceDataUuid, flags);
        dest.writeInt(mServiceData.size());
        if (mServiceData == null) {
        for (ParcelUuid uuid : mServiceData.keySet()) {
            dest.writeParcelable(uuid, flags);
            byte[] data = mServiceData.get(uuid);
            if (data == null) {
                dest.writeInt(0);
                dest.writeInt(0);
            } else {
            } else {
                dest.writeInt(1);
                dest.writeInt(1);
            dest.writeInt(mServiceData.length);
                dest.writeInt(data.length);
            dest.writeByteArray(mServiceData);
                dest.writeByteArray(data);
            }
        }
        }
        dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
        dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
        dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
        dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
@@ -209,20 +192,26 @@ public final class AdvertiseData implements Parcelable {
                            builder.addServiceUuid(uuid);
                            builder.addServiceUuid(uuid);
                        }
                        }
                    }
                    }
                    int manufacturerSize = in.readInt();
                    for (int i = 0; i < manufacturerSize; ++i) {
                        int manufacturerId = in.readInt();
                        int manufacturerId = in.readInt();
                        if (in.readInt() == 1) {
                        if (in.readInt() == 1) {
                            int manufacturerDataLength = in.readInt();
                            int manufacturerDataLength = in.readInt();
                            byte[] manufacturerData = new byte[manufacturerDataLength];
                            byte[] manufacturerData = new byte[manufacturerDataLength];
                            in.readByteArray(manufacturerData);
                            in.readByteArray(manufacturerData);
                        builder.setManufacturerData(manufacturerId, manufacturerData);
                            builder.addManufacturerData(manufacturerId, manufacturerData);
                        }
                    }
                    }
                    int serviceDataSize = in.readInt();
                    for (int i = 0; i < serviceDataSize; ++i) {
                        ParcelUuid serviceDataUuid = in.readParcelable(
                        ParcelUuid serviceDataUuid = in.readParcelable(
                                ParcelUuid.class.getClassLoader());
                                ParcelUuid.class.getClassLoader());
                        if (in.readInt() == 1) {
                        if (in.readInt() == 1) {
                            int serviceDataLength = in.readInt();
                            int serviceDataLength = in.readInt();
                            byte[] serviceData = new byte[serviceDataLength];
                            byte[] serviceData = new byte[serviceDataLength];
                            in.readByteArray(serviceData);
                            in.readByteArray(serviceData);
                        builder.setServiceData(serviceDataUuid, serviceData);
                            builder.addServiceData(serviceDataUuid, serviceData);
                        }
                    }
                    }
                    builder.setIncludeTxPowerLevel(in.readByte() == 1);
                    builder.setIncludeTxPowerLevel(in.readByte() == 1);
                    builder.setIncludeDeviceName(in.readByte() == 1);
                    builder.setIncludeDeviceName(in.readByte() == 1);
@@ -236,13 +225,8 @@ public final class AdvertiseData implements Parcelable {
    public static final class Builder {
    public static final class Builder {
        @Nullable
        @Nullable
        private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
        private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
        private int mManufacturerId = -1;
        private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
        @Nullable
        private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
        private byte[] mManufacturerSpecificData;
        @Nullable
        private ParcelUuid mServiceDataUuid;
        @Nullable
        private byte[] mServiceData;
        private boolean mIncludeTxPowerLevel;
        private boolean mIncludeTxPowerLevel;
        private boolean mIncludeDeviceName;
        private boolean mIncludeDeviceName;


@@ -268,18 +252,17 @@ public final class AdvertiseData implements Parcelable {
         * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
         * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
         *             empty.
         *             empty.
         */
         */
        public Builder setServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
        public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
            if (serviceDataUuid == null || serviceData == null) {
            if (serviceDataUuid == null || serviceData == null) {
                throw new IllegalArgumentException(
                throw new IllegalArgumentException(
                        "serviceDataUuid or serviceDataUuid is null");
                        "serviceDataUuid or serviceDataUuid is null");
            }
            }
            mServiceDataUuid = serviceDataUuid;
            mServiceData.put(serviceDataUuid, serviceData);
            mServiceData = serviceData;
            return this;
            return this;
        }
        }


        /**
        /**
         * Set manufacturer specific data.
         * Add manufacturer specific data.
         * <p>
         * <p>
         * Please refer to the Bluetooth Assigned Numbers document provided by the <a
         * Please refer to the Bluetooth Assigned Numbers document provided by the <a
         * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company
         * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company
@@ -290,7 +273,7 @@ public final class AdvertiseData implements Parcelable {
         * @throws IllegalArgumentException If the {@code manufacturerId} is negative or
         * @throws IllegalArgumentException If the {@code manufacturerId} is negative or
         *             {@code manufacturerSpecificData} is null.
         *             {@code manufacturerSpecificData} is null.
         */
         */
        public Builder setManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
        public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
            if (manufacturerId < 0) {
            if (manufacturerId < 0) {
                throw new IllegalArgumentException(
                throw new IllegalArgumentException(
                        "invalid manufacturerId - " + manufacturerId);
                        "invalid manufacturerId - " + manufacturerId);
@@ -298,8 +281,7 @@ public final class AdvertiseData implements Parcelable {
            if (manufacturerSpecificData == null) {
            if (manufacturerSpecificData == null) {
                throw new IllegalArgumentException("manufacturerSpecificData is null");
                throw new IllegalArgumentException("manufacturerSpecificData is null");
            }
            }
            mManufacturerId = manufacturerId;
            mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData);
            mManufacturerSpecificData = manufacturerSpecificData;
            return this;
            return this;
        }
        }


@@ -324,9 +306,7 @@ public final class AdvertiseData implements Parcelable {
         * Build the {@link AdvertiseData}.
         * Build the {@link AdvertiseData}.
         */
         */
        public AdvertiseData build() {
        public AdvertiseData build() {
            return new AdvertiseData(mServiceUuids,
            return new AdvertiseData(mServiceUuids, mManufacturerSpecificData, mServiceData,
                    mServiceDataUuid,
                    mServiceData, mManufacturerId, mManufacturerSpecificData,
                    mIncludeTxPowerLevel, mIncludeDeviceName);
                    mIncludeTxPowerLevel, mIncludeDeviceName);
        }
        }
    }
    }
+4 −4
Original line number Original line Diff line number Diff line
@@ -209,13 +209,13 @@ public final class BluetoothLeAdvertiser {
                        num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
                        num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
            }
            }
        }
        }
        if (data.getServiceDataUuid() != null) {
        for (ParcelUuid uuid : data.getServiceData().keySet()) {
            size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH
            size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH
                    + byteLength(data.getServiceData());
                    + byteLength(data.getServiceData().get(uuid));
        }
        }
        if (data.getManufacturerId() > 0) {
        for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH +
            size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH +
                    byteLength(data.getManufacturerSpecificData());
                    byteLength(data.getManufacturerSpecificData().valueAt(i));
        }
        }
        if (data.getIncludeTxPowerLevel()) {
        if (data.getIncludeTxPowerLevel()) {
            size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
            size += OVERHEAD_BYTES_PER_FIELD + 1; // tx power level value is one byte.
+7 −12
Original line number Original line Diff line number Diff line
@@ -242,9 +242,6 @@ public final class ScanFilter implements Parcelable {
        return mServiceDataMask;
        return mServiceDataMask;
    }
    }


    /**
     * @hide
     */
    @Nullable
    @Nullable
    public ParcelUuid getServiceDataUuid() {
    public ParcelUuid getServiceDataUuid() {
        return mServiceDataUuid;
        return mServiceDataUuid;
@@ -303,19 +300,17 @@ public final class ScanFilter implements Parcelable {
        }
        }


        // Service data match
        // Service data match
        if (mServiceData != null) {
        if (mServiceDataUuid != null) {
            if (!Objects.equals(mServiceDataUuid, scanRecord.getServiceDataUuid()) ||
            if (!matchesPartialData(mServiceData, mServiceDataMask,
                    !matchesPartialData(mServiceData, mServiceDataMask,
                    scanRecord.getServiceData(mServiceDataUuid))) {
                            scanRecord.getServiceData())) {
                return false;
                return false;
            }
            }
        }
        }


        // Manufacturer data match.
        // Manufacturer data match.
        if (mManufacturerData != null) {
        if (mManufacturerId >= 0) {
            if (mManufacturerId != scanRecord.getManufacturerId() ||
            if (!matchesPartialData(mManufacturerData, mManufacturerDataMask,
                    !matchesPartialData(mManufacturerData,
                    scanRecord.getManufacturerSpecificData(mManufacturerId))) {
                            mManufacturerDataMask, scanRecord.getManufacturerSpecificData())) {
                return false;
                return false;
            }
            }
        }
        }
+45 −44
Original line number Original line Diff line number Diff line
@@ -19,11 +19,14 @@ package android.bluetooth.le;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.bluetooth.BluetoothUuid;
import android.bluetooth.BluetoothUuid;
import android.os.ParcelUuid;
import android.os.ParcelUuid;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Log;
import android.util.SparseArray;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.List;
import java.util.List;
import java.util.Map;


/**
/**
 * Represents a scan record from Bluetooth LE scan.
 * Represents a scan record from Bluetooth LE scan.
@@ -53,14 +56,9 @@ public final class ScanRecord {
    @Nullable
    @Nullable
    private final List<ParcelUuid> mServiceUuids;
    private final List<ParcelUuid> mServiceUuids;


    private final int mManufacturerId;
    private final SparseArray<byte[]> mManufacturerSpecificData;
    @Nullable
    private final byte[] mManufacturerSpecificData;


    @Nullable
    private final Map<ParcelUuid, byte[]> mServiceData;
    private final ParcelUuid mServiceDataUuid;
    @Nullable
    private final byte[] mServiceData;


    // Transmission power level(in dB).
    // Transmission power level(in dB).
    private final int mTxPowerLevel;
    private final int mTxPowerLevel;
@@ -81,40 +79,46 @@ public final class ScanRecord {


    /**
    /**
     * Returns a list of service UUIDs within the advertisement that are used to identify the
     * Returns a list of service UUIDs within the advertisement that are used to identify the
     * bluetooth gatt services.
     * bluetooth GATT services.
     */
     */
    public List<ParcelUuid> getServiceUuids() {
    public List<ParcelUuid> getServiceUuids() {
        return mServiceUuids;
        return mServiceUuids;
    }
    }


    /**
    /**
     * Returns the manufacturer identifier, which is a non-negative number assigned by Bluetooth
     * Returns a sparse array of manufacturer identifier and its corresponding manufacturer specific
     * SIG.
     * data.
     */
     */
    public int getManufacturerId() {
    public SparseArray<byte[]> getManufacturerSpecificData() {
        return mManufacturerId;
        return mManufacturerSpecificData;
    }
    }


    /**
    /**
     * Returns the manufacturer specific data which is the content of manufacturer specific data
     * Returns the manufacturer specific data associated with the manufacturer id. Returns
     * field.
     * {@code null} if the {@code manufacturerId} is not found.
     */
     */
    public byte[] getManufacturerSpecificData() {
    @Nullable
        return mManufacturerSpecificData;
    public byte[] getManufacturerSpecificData(int manufacturerId) {
        return mManufacturerSpecificData.get(manufacturerId);
    }
    }


    /**
    /**
     * Returns a 16-bit UUID of the service that the service data is associated with.
     * Returns a map of service UUID and its corresponding service data.
     */
     */
    public ParcelUuid getServiceDataUuid() {
    public Map<ParcelUuid, byte[]> getServiceData() {
        return mServiceDataUuid;
        return mServiceData;
    }
    }


    /**
    /**
     * Returns service data.
     * Returns the service data byte array associated with the {@code serviceUuid}. Returns
     * {@code null} if the {@code serviceDataUuid} is not found.
     */
     */
    public byte[] getServiceData() {
    @Nullable
        return mServiceData;
    public byte[] getServiceData(ParcelUuid serviceDataUuid) {
        if (serviceDataUuid == null) {
            return null;
        }
        return mServiceData.get(serviceDataUuid);
    }
    }


    /**
    /**
@@ -144,14 +148,12 @@ public final class ScanRecord {
    }
    }


    private ScanRecord(List<ParcelUuid> serviceUuids,
    private ScanRecord(List<ParcelUuid> serviceUuids,
            ParcelUuid serviceDataUuid, byte[] serviceData,
            SparseArray<byte[]> manufacturerData,
            int manufacturerId,
            Map<ParcelUuid, byte[]> serviceData,
            byte[] manufacturerSpecificData, int advertiseFlags, int txPowerLevel,
            int advertiseFlags, int txPowerLevel,
            String localName, byte[] bytes) {
            String localName, byte[] bytes) {
        mServiceUuids = serviceUuids;
        mServiceUuids = serviceUuids;
        mManufacturerId = manufacturerId;
        mManufacturerSpecificData = manufacturerData;
        mManufacturerSpecificData = manufacturerSpecificData;
        mServiceDataUuid = serviceDataUuid;
        mServiceData = serviceData;
        mServiceData = serviceData;
        mDeviceName = localName;
        mDeviceName = localName;
        mAdvertiseFlags = advertiseFlags;
        mAdvertiseFlags = advertiseFlags;
@@ -168,7 +170,6 @@ public final class ScanRecord {
     * order.
     * order.
     *
     *
     * @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
     * @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
     *
     * @hide
     * @hide
     */
     */
    public static ScanRecord parseFromBytes(byte[] scanRecord) {
    public static ScanRecord parseFromBytes(byte[] scanRecord) {
@@ -181,10 +182,9 @@ public final class ScanRecord {
        List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
        List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
        String localName = null;
        String localName = null;
        int txPowerLevel = Integer.MIN_VALUE;
        int txPowerLevel = Integer.MIN_VALUE;
        ParcelUuid serviceDataUuid = null;

        byte[] serviceData = null;
        SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
        int manufacturerId = -1;
        Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();
        byte[] manufacturerSpecificData = null;


        try {
        try {
            while (currentPos < scanRecord.length) {
            while (currentPos < scanRecord.length) {
@@ -230,16 +230,20 @@ public final class ScanRecord {
                        int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
                        int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
                        byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
                        byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
                                serviceUuidLength);
                                serviceUuidLength);
                        serviceDataUuid = BluetoothUuid.parseUuidFrom(serviceDataUuidBytes);
                        ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(
                        serviceData = extractBytes(scanRecord, currentPos + 2, dataLength - 2);
                                serviceDataUuidBytes);
                        byte[] serviceDataArray = extractBytes(scanRecord,
                                currentPos + serviceUuidLength, dataLength - serviceUuidLength);
                        serviceData.put(serviceDataUuid, serviceDataArray);
                        break;
                        break;
                    case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
                    case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
                        // The first two bytes of the manufacturer specific data are
                        // The first two bytes of the manufacturer specific data are
                        // manufacturer ids in little endian.
                        // manufacturer ids in little endian.
                        manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) +
                        int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) +
                                (scanRecord[currentPos] & 0xFF);
                                (scanRecord[currentPos] & 0xFF);
                        manufacturerSpecificData = extractBytes(scanRecord, currentPos + 2,
                        byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
                                dataLength - 2);
                                dataLength - 2);
                        manufacturerData.put(manufacturerId, manufacturerDataBytes);
                        break;
                        break;
                    default:
                    default:
                        // Just ignore, we don't handle such data type.
                        // Just ignore, we don't handle such data type.
@@ -251,9 +255,8 @@ public final class ScanRecord {
            if (serviceUuids.isEmpty()) {
            if (serviceUuids.isEmpty()) {
                serviceUuids = null;
                serviceUuids = null;
            }
            }
            return new ScanRecord(serviceUuids, serviceDataUuid, serviceData,
            return new ScanRecord(serviceUuids, manufacturerData, serviceData,
                    manufacturerId, manufacturerSpecificData, advertiseFlag, txPowerLevel,
                    advertiseFlag, txPowerLevel, localName, scanRecord);
                    localName, scanRecord);
        } catch (IndexOutOfBoundsException e) {
        } catch (IndexOutOfBoundsException e) {
            Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
            Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
            return null;
            return null;
@@ -263,13 +266,11 @@ public final class ScanRecord {
    @Override
    @Override
    public String toString() {
    public String toString() {
        return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
        return "ScanRecord [mAdvertiseFlags=" + mAdvertiseFlags + ", mServiceUuids=" + mServiceUuids
                + ", mManufacturerId=" + mManufacturerId + ", mManufacturerSpecificData="
                + ", mManufacturerSpecificData=" + Utils.toString(mManufacturerSpecificData)
                + Arrays.toString(mManufacturerSpecificData) + ", mServiceDataUuid="
                + ", mServiceData=" + Utils.toString(mServiceData)
                + mServiceDataUuid + ", mServiceData=" + Arrays.toString(mServiceData)
                + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
                + ", mTxPowerLevel=" + mTxPowerLevel + ", mDeviceName=" + mDeviceName + "]";
    }
    }



    // Parse service UUIDs.
    // Parse service UUIDs.
    private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength,
    private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength,
            int uuidLength, List<ParcelUuid> serviceUuids) {
            int uuidLength, List<ParcelUuid> serviceUuids) {
Loading