blob: b65c31d1dcf765f788e492abe402387e4541f5cd [file] [log] [blame]
Wei Wang6d811182014-05-22 12:10:25 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.bluetooth.le;
18
19import android.annotation.Nullable;
Wei Wang6d811182014-05-22 12:10:25 -070020import android.os.Parcel;
21import android.os.ParcelUuid;
22import android.os.Parcelable;
Wei Wang6bf513d2014-08-01 11:12:37 -070023import android.util.ArrayMap;
24import android.util.SparseArray;
Wei Wang6d811182014-05-22 12:10:25 -070025
26import java.util.ArrayList;
Wei Wang6d811182014-05-22 12:10:25 -070027import java.util.List;
Wei Wang6bf513d2014-08-01 11:12:37 -070028import java.util.Map;
Wei Wang03259472014-07-23 00:33:44 -070029import java.util.Objects;
Wei Wang6d811182014-05-22 12:10:25 -070030
31/**
Wei Wang685c17582014-07-16 22:02:03 -070032 * Advertise data packet container for Bluetooth LE advertising. This represents the data to be
Wei Wangaf74e662014-07-09 14:03:42 -070033 * advertised as well as the scan response data for active scans.
Wei Wang685c17582014-07-16 22:02:03 -070034 * <p>
35 * Use {@link AdvertiseData.Builder} to create an instance of {@link AdvertiseData} to be
Wei Wang6d811182014-05-22 12:10:25 -070036 * advertised.
37 *
38 * @see BluetoothLeAdvertiser
39 * @see ScanRecord
40 */
Wei Wangaf74e662014-07-09 14:03:42 -070041public final class AdvertiseData implements Parcelable {
Wei Wang6d811182014-05-22 12:10:25 -070042
43 @Nullable
44 private final List<ParcelUuid> mServiceUuids;
45
Wei Wang6bf513d2014-08-01 11:12:37 -070046 private final SparseArray<byte[]> mManufacturerSpecificData;
47 private final Map<ParcelUuid, byte[]> mServiceData;
Wei Wang685c17582014-07-16 22:02:03 -070048 private final boolean mIncludeTxPowerLevel;
49 private final boolean mIncludeDeviceName;
Wei Wang6d811182014-05-22 12:10:25 -070050
Wei Wangaf74e662014-07-09 14:03:42 -070051 private AdvertiseData(List<ParcelUuid> serviceUuids,
Wei Wang6bf513d2014-08-01 11:12:37 -070052 SparseArray<byte[]> manufacturerData,
53 Map<ParcelUuid, byte[]> serviceData,
54 boolean includeTxPowerLevel,
Wei Wang685c17582014-07-16 22:02:03 -070055 boolean includeDeviceName) {
Wei Wang6d811182014-05-22 12:10:25 -070056 mServiceUuids = serviceUuids;
Wei Wang6bf513d2014-08-01 11:12:37 -070057 mManufacturerSpecificData = manufacturerData;
Wei Wang6d811182014-05-22 12:10:25 -070058 mServiceData = serviceData;
59 mIncludeTxPowerLevel = includeTxPowerLevel;
Wei Wang685c17582014-07-16 22:02:03 -070060 mIncludeDeviceName = includeDeviceName;
Wei Wang6d811182014-05-22 12:10:25 -070061 }
62
63 /**
Wei Wangaf74e662014-07-09 14:03:42 -070064 * Returns a list of service UUIDs within the advertisement that are used to identify the
65 * Bluetooth GATT services.
Wei Wang6d811182014-05-22 12:10:25 -070066 */
67 public List<ParcelUuid> getServiceUuids() {
68 return mServiceUuids;
69 }
70
71 /**
Wei Wang6bf513d2014-08-01 11:12:37 -070072 * Returns an array of manufacturer Id and the corresponding manufacturer specific data. The
73 * manufacturer id is a non-negative number assigned by Bluetooth SIG.
Wei Wang6d811182014-05-22 12:10:25 -070074 */
Wei Wang6bf513d2014-08-01 11:12:37 -070075 public SparseArray<byte[]> getManufacturerSpecificData() {
Wei Wang6d811182014-05-22 12:10:25 -070076 return mManufacturerSpecificData;
77 }
78
79 /**
Wei Wang6bf513d2014-08-01 11:12:37 -070080 * Returns a map of 16-bit UUID and its corresponding service data.
Wei Wang6d811182014-05-22 12:10:25 -070081 */
Wei Wang6bf513d2014-08-01 11:12:37 -070082 public Map<ParcelUuid, byte[]> getServiceData() {
Wei Wang6d811182014-05-22 12:10:25 -070083 return mServiceData;
84 }
85
86 /**
87 * Whether the transmission power level will be included in the advertisement packet.
88 */
89 public boolean getIncludeTxPowerLevel() {
90 return mIncludeTxPowerLevel;
91 }
92
Wei Wang685c17582014-07-16 22:02:03 -070093 /**
94 * Whether the device name will be included in the advertisement packet.
95 */
96 public boolean getIncludeDeviceName() {
97 return mIncludeDeviceName;
98 }
99
Wei Wang03259472014-07-23 00:33:44 -0700100 /**
101 * @hide
102 */
103 @Override
104 public int hashCode() {
Wei Wang6bf513d2014-08-01 11:12:37 -0700105 return Objects.hash(mServiceUuids, mManufacturerSpecificData, mServiceData,
106 mIncludeDeviceName, mIncludeTxPowerLevel);
Wei Wang03259472014-07-23 00:33:44 -0700107 }
108
109 /**
110 * @hide
111 */
112 @Override
113 public boolean equals(Object obj) {
114 if (this == obj) {
115 return true;
116 }
117 if (obj == null || getClass() != obj.getClass()) {
118 return false;
119 }
120 AdvertiseData other = (AdvertiseData) obj;
Jack He2992cd02017-08-22 21:21:23 -0700121 return Objects.equals(mServiceUuids, other.mServiceUuids)
122 && BluetoothLeUtils.equals(mManufacturerSpecificData,
123 other.mManufacturerSpecificData)
124 && BluetoothLeUtils.equals(mServiceData, other.mServiceData)
125 && mIncludeDeviceName == other.mIncludeDeviceName
126 && mIncludeTxPowerLevel == other.mIncludeTxPowerLevel;
Wei Wang03259472014-07-23 00:33:44 -0700127 }
128
Wei Wang6d811182014-05-22 12:10:25 -0700129 @Override
130 public String toString() {
Wei Wang6bf513d2014-08-01 11:12:37 -0700131 return "AdvertiseData [mServiceUuids=" + mServiceUuids + ", mManufacturerSpecificData="
Wei Wang833559d2014-08-29 10:26:13 -0700132 + BluetoothLeUtils.toString(mManufacturerSpecificData) + ", mServiceData="
133 + BluetoothLeUtils.toString(mServiceData)
Wei Wang03259472014-07-23 00:33:44 -0700134 + ", mIncludeTxPowerLevel=" + mIncludeTxPowerLevel + ", mIncludeDeviceName="
135 + mIncludeDeviceName + "]";
Wei Wang6d811182014-05-22 12:10:25 -0700136 }
137
138 @Override
139 public int describeContents() {
140 return 0;
141 }
142
143 @Override
144 public void writeToParcel(Parcel dest, int flags) {
Jakub Pawlowskie8c3b912017-08-08 15:47:57 -0700145 dest.writeTypedArray(mServiceUuids.toArray(new ParcelUuid[mServiceUuids.size()]), flags);
Wei Wang6d811182014-05-22 12:10:25 -0700146
Wei Wang6bf513d2014-08-01 11:12:37 -0700147 // mManufacturerSpecificData could not be null.
148 dest.writeInt(mManufacturerSpecificData.size());
149 for (int i = 0; i < mManufacturerSpecificData.size(); ++i) {
150 dest.writeInt(mManufacturerSpecificData.keyAt(i));
Jakub Pawlowskie8c3b912017-08-08 15:47:57 -0700151 dest.writeByteArray(mManufacturerSpecificData.valueAt(i));
Wei Wang6d811182014-05-22 12:10:25 -0700152 }
Wei Wang6bf513d2014-08-01 11:12:37 -0700153 dest.writeInt(mServiceData.size());
154 for (ParcelUuid uuid : mServiceData.keySet()) {
Jakub Pawlowskie8c3b912017-08-08 15:47:57 -0700155 dest.writeTypedObject(uuid, flags);
156 dest.writeByteArray(mServiceData.get(uuid));
Wei Wang6d811182014-05-22 12:10:25 -0700157 }
158 dest.writeByte((byte) (getIncludeTxPowerLevel() ? 1 : 0));
Wei Wang685c17582014-07-16 22:02:03 -0700159 dest.writeByte((byte) (getIncludeDeviceName() ? 1 : 0));
Wei Wang6d811182014-05-22 12:10:25 -0700160 }
161
Wei Wangaf74e662014-07-09 14:03:42 -0700162 public static final Parcelable.Creator<AdvertiseData> CREATOR =
163 new Creator<AdvertiseData>() {
Jack Hea355e5e2017-08-22 16:06:54 -0700164 @Override
Wei Wangaf74e662014-07-09 14:03:42 -0700165 public AdvertiseData[] newArray(int size) {
166 return new AdvertiseData[size];
Wei Wang6d811182014-05-22 12:10:25 -0700167 }
168
Jack Hea355e5e2017-08-22 16:06:54 -0700169 @Override
Wei Wangaf74e662014-07-09 14:03:42 -0700170 public AdvertiseData createFromParcel(Parcel in) {
Wei Wang6d811182014-05-22 12:10:25 -0700171 Builder builder = new Builder();
Jakub Pawlowskie8c3b912017-08-08 15:47:57 -0700172 ArrayList<ParcelUuid> uuids = in.createTypedArrayList(ParcelUuid.CREATOR);
173 for (ParcelUuid uuid : uuids) {
174 builder.addServiceUuid(uuid);
Wei Wang6d811182014-05-22 12:10:25 -0700175 }
Jakub Pawlowskie8c3b912017-08-08 15:47:57 -0700176
Wei Wang6bf513d2014-08-01 11:12:37 -0700177 int manufacturerSize = in.readInt();
178 for (int i = 0; i < manufacturerSize; ++i) {
179 int manufacturerId = in.readInt();
Jakub Pawlowskie8c3b912017-08-08 15:47:57 -0700180 byte[] manufacturerData = in.createByteArray();
181 builder.addManufacturerData(manufacturerId, manufacturerData);
Wei Wang6d811182014-05-22 12:10:25 -0700182 }
Wei Wang6bf513d2014-08-01 11:12:37 -0700183 int serviceDataSize = in.readInt();
184 for (int i = 0; i < serviceDataSize; ++i) {
Jakub Pawlowskie8c3b912017-08-08 15:47:57 -0700185 ParcelUuid serviceDataUuid = in.readTypedObject(ParcelUuid.CREATOR);
186 byte[] serviceData = in.createByteArray();
187 builder.addServiceData(serviceDataUuid, serviceData);
Wei Wang6d811182014-05-22 12:10:25 -0700188 }
189 builder.setIncludeTxPowerLevel(in.readByte() == 1);
Wei Wang685c17582014-07-16 22:02:03 -0700190 builder.setIncludeDeviceName(in.readByte() == 1);
Wei Wang6d811182014-05-22 12:10:25 -0700191 return builder.build();
192 }
193 };
194
195 /**
Wei Wangaf74e662014-07-09 14:03:42 -0700196 * Builder for {@link AdvertiseData}.
Wei Wang6d811182014-05-22 12:10:25 -0700197 */
198 public static final class Builder {
Wei Wang6d811182014-05-22 12:10:25 -0700199 @Nullable
Wei Wang685c17582014-07-16 22:02:03 -0700200 private List<ParcelUuid> mServiceUuids = new ArrayList<ParcelUuid>();
Wei Wang6bf513d2014-08-01 11:12:37 -0700201 private SparseArray<byte[]> mManufacturerSpecificData = new SparseArray<byte[]>();
202 private Map<ParcelUuid, byte[]> mServiceData = new ArrayMap<ParcelUuid, byte[]>();
Wei Wang685c17582014-07-16 22:02:03 -0700203 private boolean mIncludeTxPowerLevel;
204 private boolean mIncludeDeviceName;
Wei Wang6d811182014-05-22 12:10:25 -0700205
206 /**
Wei Wang685c17582014-07-16 22:02:03 -0700207 * Add a service UUID to advertise data.
Wei Wang6d811182014-05-22 12:10:25 -0700208 *
Wei Wang685c17582014-07-16 22:02:03 -0700209 * @param serviceUuid A service UUID to be advertised.
Wei Wang6d811182014-05-22 12:10:25 -0700210 * @throws IllegalArgumentException If the {@code serviceUuids} are null.
211 */
Wei Wang685c17582014-07-16 22:02:03 -0700212 public Builder addServiceUuid(ParcelUuid serviceUuid) {
213 if (serviceUuid == null) {
Wei Wang6d811182014-05-22 12:10:25 -0700214 throw new IllegalArgumentException("serivceUuids are null");
215 }
Wei Wang685c17582014-07-16 22:02:03 -0700216 mServiceUuids.add(serviceUuid);
Wei Wang6d811182014-05-22 12:10:25 -0700217 return this;
218 }
219
220 /**
Wei Wang685c17582014-07-16 22:02:03 -0700221 * Add service data to advertise data.
Wei Wang6d811182014-05-22 12:10:25 -0700222 *
Wei Wangaf74e662014-07-09 14:03:42 -0700223 * @param serviceDataUuid 16-bit UUID of the service the data is associated with
224 * @param serviceData Service data
Wei Wang6d811182014-05-22 12:10:25 -0700225 * @throws IllegalArgumentException If the {@code serviceDataUuid} or {@code serviceData} is
Jack Hea355e5e2017-08-22 16:06:54 -0700226 * empty.
Wei Wang6d811182014-05-22 12:10:25 -0700227 */
Wei Wang6bf513d2014-08-01 11:12:37 -0700228 public Builder addServiceData(ParcelUuid serviceDataUuid, byte[] serviceData) {
Wei Wang6d811182014-05-22 12:10:25 -0700229 if (serviceDataUuid == null || serviceData == null) {
230 throw new IllegalArgumentException(
231 "serviceDataUuid or serviceDataUuid is null");
232 }
Wei Wang6bf513d2014-08-01 11:12:37 -0700233 mServiceData.put(serviceDataUuid, serviceData);
Wei Wang6d811182014-05-22 12:10:25 -0700234 return this;
235 }
236
237 /**
Wei Wang6bf513d2014-08-01 11:12:37 -0700238 * Add manufacturer specific data.
Wei Wang685c17582014-07-16 22:02:03 -0700239 * <p>
240 * Please refer to the Bluetooth Assigned Numbers document provided by the <a
241 * href="https://www.bluetooth.org">Bluetooth SIG</a> for a list of existing company
242 * identifiers.
Wei Wangaf74e662014-07-09 14:03:42 -0700243 *
244 * @param manufacturerId Manufacturer ID assigned by Bluetooth SIG.
245 * @param manufacturerSpecificData Manufacturer specific data
Jack Hea355e5e2017-08-22 16:06:54 -0700246 * @throws IllegalArgumentException If the {@code manufacturerId} is negative or {@code
247 * manufacturerSpecificData} is null.
Wei Wang6d811182014-05-22 12:10:25 -0700248 */
Wei Wang6bf513d2014-08-01 11:12:37 -0700249 public Builder addManufacturerData(int manufacturerId, byte[] manufacturerSpecificData) {
Wei Wang6d811182014-05-22 12:10:25 -0700250 if (manufacturerId < 0) {
251 throw new IllegalArgumentException(
252 "invalid manufacturerId - " + manufacturerId);
253 }
254 if (manufacturerSpecificData == null) {
255 throw new IllegalArgumentException("manufacturerSpecificData is null");
256 }
Wei Wang6bf513d2014-08-01 11:12:37 -0700257 mManufacturerSpecificData.put(manufacturerId, manufacturerSpecificData);
Wei Wang6d811182014-05-22 12:10:25 -0700258 return this;
259 }
260
261 /**
Wei Wang685c17582014-07-16 22:02:03 -0700262 * Whether the transmission power level should be included in the advertise packet. Tx power
263 * level field takes 3 bytes in advertise packet.
Wei Wang6d811182014-05-22 12:10:25 -0700264 */
265 public Builder setIncludeTxPowerLevel(boolean includeTxPowerLevel) {
266 mIncludeTxPowerLevel = includeTxPowerLevel;
267 return this;
268 }
269
270 /**
Wei Wang685c17582014-07-16 22:02:03 -0700271 * Set whether the device name should be included in advertise packet.
272 */
273 public Builder setIncludeDeviceName(boolean includeDeviceName) {
274 mIncludeDeviceName = includeDeviceName;
275 return this;
276 }
277
278 /**
Wei Wangaf74e662014-07-09 14:03:42 -0700279 * Build the {@link AdvertiseData}.
Wei Wang6d811182014-05-22 12:10:25 -0700280 */
Wei Wangaf74e662014-07-09 14:03:42 -0700281 public AdvertiseData build() {
Wei Wang6bf513d2014-08-01 11:12:37 -0700282 return new AdvertiseData(mServiceUuids, mManufacturerSpecificData, mServiceData,
Wei Wang685c17582014-07-16 22:02:03 -0700283 mIncludeTxPowerLevel, mIncludeDeviceName);
Wei Wang6d811182014-05-22 12:10:25 -0700284 }
Wei Wang6d811182014-05-22 12:10:25 -0700285 }
286}