diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2022-01-18 23:59:58 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2022-01-18 23:59:58 +0000 |
commit | d15d8266b900c549d2eed52c56f82d7c3c3792c8 (patch) | |
tree | 0b7c4c70453c091e24e37758ff1b1fd49bf20eb3 /framework/java/android/bluetooth/le/AdvertiseData.java | |
parent | 7d69d903a5ee30dac4abc82e056f2b8ec0278708 (diff) | |
parent | aa6d8f71ae61c0e57b35258c00d28fcba5154f09 (diff) |
Merge changes from topic "migrate-sc-bt" into sc-v2-dev-plus-aosp
* changes:
Migrating BT files into packages/modules/Bluetooth
Merge history of Bluetooth API from frameworks/base
Diffstat (limited to 'framework/java/android/bluetooth/le/AdvertiseData.java')
-rw-r--r-- | framework/java/android/bluetooth/le/AdvertiseData.java | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/framework/java/android/bluetooth/le/AdvertiseData.java b/framework/java/android/bluetooth/le/AdvertiseData.java new file mode 100644 index 0000000000..fdf62ec3a6 --- /dev/null +++ b/framework/java/android/bluetooth/le/AdvertiseData.java @@ -0,0 +1,374 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.bluetooth.le; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.ParcelUuid; +import android.os.Parcelable; +import android.util.ArrayMap; +import android.util.SparseArray; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Advertise data packet container for Bluetooth LE advertising. This represents the data to be + * advertised as well as the scan response data for active scans. + * <p> + * Use {@link AdvertiseData.Builder} to create an instance of {@link AdvertiseData} to be + * advertised. + * + * @see BluetoothLeAdvertiser + * @see ScanRecord + */ +public final class AdvertiseData implements Parcelable { + + @Nullable + private final List<ParcelUuid> mServiceUuids; + + @NonNull + private final List<ParcelUuid> mServiceSolicitationUuids; + + @Nullable + private final List<TransportDiscoveryData> mTransportDiscoveryData; + + private final SparseArray<byte[]> mManufacturerSpecificData; + private final Map<ParcelUuid, byte[]> mServiceData; + private final boolean mIncludeTxPowerLevel; + private final boolean mIncludeDeviceName; + + private AdvertiseData(List<ParcelUuid> serviceUuids, + List<ParcelUuid> serviceSolicitationUuids, + List<TransportDiscoveryData> transportDiscoveryData, + SparseArray<byte[]> manufacturerData, + Map<ParcelUuid, byte[]> serviceData, + boolean includeTxPowerLevel, + boolean includeDeviceName) { + mServiceUuids = serviceUuids; + mServiceSolicitationUuids = serviceSolicitationUuids; + mTransportDiscoveryData = transportDiscoveryData; + mManufacturerSpecificData = manufacturerData; + mServiceData = serviceData; + mIncludeTxPowerLevel = includeTxPowerLevel; + mIncludeDeviceName = includeDeviceName; + } + + /** + * Returns a list of service UUIDs within the advertisement that are used to identify the + * Bluetooth GATT services. + */ + public List<ParcelUuid> getServiceUuids() { + return mServiceUuids; + } + + /** + * Returns a list of service solicitation UUIDs within the advertisement that we invite to connect. + */ + @NonNull + public List<ParcelUuid> getServiceSolicitationUuids() { + return mServiceSolicitationUuids; + } + + /** + * Returns a list of {@link TransportDiscoveryData} within the advertisement. + */ + @NonNull + public List<TransportDiscoveryData> getTransportDiscoveryData() { + if (mTransportDiscoveryData == null) { + return Collections.emptyList(); + } + return mTransportDiscoveryData; + } + + /** + * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The + * manufacturer id is a non-negative number assigned by Bluetooth SIG. + */ + public SparseArray<byte[]> getManufacturerSpecificData() { + return mManufacturerSpecificData; + } + + /** + * Returns a map of 16-bit UUID and its corresponding service data. + */ + public Map<ParcelUuid, byte[]> getServiceData() { + return mServiceData; + } + + /** + * Whether the transmission power level will be included in the advertisement packet. + */ + public boolean getIncludeTxPowerLevel() { + return mIncludeTxPowerLevel; + } + + /** + * Whether the device name will be included in the advertisement packet. + */ + public boolean getIncludeDeviceName() { + return mIncludeDeviceName; + } + + /** + * @hide + */ + @Override + public int hashCode() { + return Objects.hash(mServiceUuids, mServiceSolicitationUuids, mTransportDiscoveryData, + mManufacturerSpecificData, mServiceData, mIncludeDeviceName, mIncludeTxPowerLevel); + } + + /** + * @hide + */ + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + AdvertiseData other = (AdvertiseData) obj; + return Objects.equals(mServiceUuids, other.mServiceUuids) + && Objects.equals(mServiceSolicitationUuids, other.mServiceSolicitationUuids) + && Objects.equals(mTransportDiscoveryData, other.mTransportDiscoveryData) + && BluetoothLeUtils.equals(mManufacturerSpecificData, + other.mManufacturerSpecificData) + && BluetoothLeUtils.equals(mServiceData, other.mServiceData) + && mIncludeDeviceName == other.mIncludeDeviceName + && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel; + } + + @Override + public String toString() { + return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mServiceSolicitationUuids=" + + mServiceSolicitationUuids + ", mTransportDiscoveryData=" + + mTransportDiscoveryData + ", mManufacturerSpecificData=" + + BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData=" + + BluetoothLeUtils.toString(mServiceData) + + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName=" + + mIncludeDeviceName + "]"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeTypedArray(mServiceUuids.toArray(new ParcelUuid[mServiceUuids.size()]), flags); + dest.writeTypedArray(mServiceSolicitationUuids.toArray( + new ParcelUuid[mServiceSolicitationUuids.size()]), flags); + + dest.writeTypedList(mTransportDiscoveryData); + + // mManufacturerSpecificData could not be null. + dest.writeInt(mManufacturerSpecificData.size()); + for (int i = 0; i < mManufacturerSpecificData.size(); ++i) { + dest.writeInt(mManufacturerSpecificData.keyAt(i)); + dest.writeByteArray(mManufacturerSpecificData.valueAt(i)); + } + dest.writeInt(mServiceData.size()); + for (ParcelUuid uuid : mServiceData.keySet()) { + dest.writeTypedObject(uuid, flags); + dest.writeByteArray(mServiceData.get(uuid)); + } + dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0)); + dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0)); + } + + public static final @android.annotation.NonNull Parcelable.Creator<AdvertiseData> CREATOR = + new Creator<AdvertiseData>() { + @Override + public AdvertiseData[] newArray(int size) { + return new AdvertiseData[size]; + } + + @Override + public AdvertiseData createFromParcel(Parcel in) { + Builder builder = new Builder(); + ArrayList<ParcelUuid> uuids = in.createTypedArrayList(ParcelUuid.CREATOR); + for (ParcelUuid uuid : uuids) { + builder.addServiceUuid(uuid); + } + + ArrayList<ParcelUuid> solicitationUuids = in.createTypedArrayList(ParcelUuid.CREATOR); + for (ParcelUuid uuid : solicitationUuids) { + builder.addServiceSolicitationUuid(uuid); + } + + List<TransportDiscoveryData> transportDiscoveryData = + in.createTypedArrayList(TransportDiscoveryData.CREATOR); + for (TransportDiscoveryData tdd : transportDiscoveryData) { + builder.addTransportDiscoveryData(tdd); + } + + int manufacturerSize = in.readInt(); + for (int i = 0; i < manufacturerSize; ++i) { + int manufacturerId = in.readInt(); + byte[] manufacturerData = in.createByteArray(); + builder.addManufacturerData(manufacturerId, manufacturerData); + } + int serviceDataSize = in.readInt(); + for (int i = 0; i < serviceDataSize; ++i) { + ParcelUuid serviceDataUuid = in.readTypedObject(ParcelUuid.CREATOR); + byte[] serviceData = in.createByteArray(); + builder.addServiceData(serviceDataUuid, serviceData); + } + builder.setIncludeTxPowerLevel(in.readByte() == 1); + builder.setIncludeDeviceName(in.readByte() == 1); + return builder.build(); + } + }; + + /** + * Builder for {@link AdvertiseData}. + */ + public static final class Builder { + @Nullable + private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>(); + @NonNull + private List<ParcelUuid> mServiceSolicitationUuids = new ArrayList<ParcelUuid>(); + @Nullable + private List<TransportDiscoveryData> mTransportDiscoveryData = + new ArrayList<TransportDiscoveryData>(); + private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>(); + private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>(); + private boolean mIncludeTxPowerLevel; + private boolean mIncludeDeviceName; + + /** + * Add a service UUID to advertise data. + * + * @param serviceUuid A service UUID to be advertised. + * @throws IllegalArgumentException If the {@code serviceUuid} is null. + */ + public Builder addServiceUuid(ParcelUuid serviceUuid) { + if (serviceUuid == null) { + throw new IllegalArgumentException("serviceUuid is null"); + } + mServiceUuids.add(serviceUuid); + return this; + } + + /** + * Add a service solicitation UUID to advertise data. + * + * @param serviceSolicitationUuid A service solicitation UUID to be advertised. + * @throws IllegalArgumentException If the {@code serviceSolicitationUuid} is null. + */ + @NonNull + public Builder addServiceSolicitationUuid(@NonNull ParcelUuid serviceSolicitationUuid) { + if (serviceSolicitationUuid == null) { + throw new IllegalArgumentException("serviceSolicitationUuid is null"); + } + mServiceSolicitationUuids.add(serviceSolicitationUuid); + return this; + } + + /** + * Add service data to advertise data. + * + * @param serviceDataUuid 16-bit UUID of the service the data is associated with + * @param serviceData Service data + * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is + * empty. + */ + public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) { + if (serviceDataUuid == null || serviceData == null) { + throw new IllegalArgumentException( + "serviceDataUuid or serviceDataUuid is null"); + } + mServiceData.put(serviceDataUuid, serviceData); + return this; + } + + /** + * Add Transport Discovery Data to advertise data. + * + * @param transportDiscoveryData Transport Discovery Data, consisting of one or more + * Transport Blocks. Transport Discovery Data AD Type Code is already included. + * @throws IllegalArgumentException If the {@code transportDiscoveryData} is empty + */ + @NonNull + public Builder addTransportDiscoveryData( + @NonNull TransportDiscoveryData transportDiscoveryData) { + if (transportDiscoveryData == null) { + throw new IllegalArgumentException("transportDiscoveryData is null"); + } + mTransportDiscoveryData.add(transportDiscoveryData); + return this; + } + + /** + * Add manufacturer specific data. + * <p> + * 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 + * identifiers. + * + * @param manufacturerId Manufacturer ID assigned by Bluetooth SIG. + * @param manufacturerSpecificData Manufacturer specific data + * @throws IllegalArgumentException If the {@code manufacturerId} is negative or {@code + * manufacturerSpecificData} is null. + */ + public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) { + if (manufacturerId < 0) { + throw new IllegalArgumentException( + "invalid manufacturerId - " + manufacturerId); + } + if (manufacturerSpecificData == null) { + throw new IllegalArgumentException("manufacturerSpecificData is null"); + } + mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData); + return this; + } + + /** + * Whether the transmission power level should be included in the advertise packet. Tx power + * level field takes 3 bytes in advertise packet. + */ + public Builder setIncludeTxPowerLevel(boolean includeTxPowerLevel) { + mIncludeTxPowerLevel = includeTxPowerLevel; + return this; + } + + /** + * Set whether the device name should be included in advertise packet. + */ + public Builder setIncludeDeviceName(boolean includeDeviceName) { + mIncludeDeviceName = includeDeviceName; + return this; + } + + /** + * Build the {@link AdvertiseData}. + */ + public AdvertiseData build() { + return new AdvertiseData(mServiceUuids, mServiceSolicitationUuids, + mTransportDiscoveryData, mManufacturerSpecificData, mServiceData, + mIncludeTxPowerLevel, mIncludeDeviceName); + } + } +} |