• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 
17 package android.bluetooth;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.List;
30 import java.util.Objects;
31 
32 /**
33  * This class contains the broadcast group settings information for this Broadcast Group.
34  *
35  * @hide
36  */
37 @SystemApi
38 public final class BluetoothLeBroadcastSettings implements Parcelable {
39     private final boolean mIsPublicBroadcast;
40     private final String mBroadcastName;
41     private final byte[] mBroadcastCode;
42     private final BluetoothLeAudioContentMetadata mPublicBroadcastMetadata;
43     private final List<BluetoothLeBroadcastSubgroupSettings> mSubgroupSettings;
44 
BluetoothLeBroadcastSettings( boolean isPublicBroadcast, String broadcastName, byte[] broadcastCode, BluetoothLeAudioContentMetadata publicBroadcastMetadata, List<BluetoothLeBroadcastSubgroupSettings> subgroupSettings)45     private BluetoothLeBroadcastSettings(
46             boolean isPublicBroadcast,
47             String broadcastName,
48             byte[] broadcastCode,
49             BluetoothLeAudioContentMetadata publicBroadcastMetadata,
50             List<BluetoothLeBroadcastSubgroupSettings> subgroupSettings) {
51         mIsPublicBroadcast = isPublicBroadcast;
52         mBroadcastName = broadcastName;
53         mBroadcastCode = broadcastCode;
54         mPublicBroadcastMetadata = publicBroadcastMetadata;
55         mSubgroupSettings = subgroupSettings;
56     }
57 
58     @Override
equals(@ullable Object o)59     public boolean equals(@Nullable Object o) {
60         if (!(o instanceof BluetoothLeBroadcastSettings)) {
61             return false;
62         }
63         final BluetoothLeBroadcastSettings other = (BluetoothLeBroadcastSettings) o;
64         return mIsPublicBroadcast == other.isPublicBroadcast()
65                 && Objects.equals(mBroadcastName, other.getBroadcastName())
66                 && Arrays.equals(mBroadcastCode, other.getBroadcastCode())
67                 && Objects.equals(mPublicBroadcastMetadata, other.getPublicBroadcastMetadata())
68                 && mSubgroupSettings.equals(other.getSubgroupSettings());
69     }
70 
71     @Override
hashCode()72     public int hashCode() {
73         return Objects.hash(
74                 mIsPublicBroadcast,
75                 mBroadcastName,
76                 Arrays.hashCode(mBroadcastCode),
77                 mPublicBroadcastMetadata,
78                 mSubgroupSettings);
79     }
80 
81     /**
82      * Return {@code true} if this Broadcast Group is set to broadcast Public Broadcast Announcement
83      * otherwise return {@code false}.
84      *
85      * @hide
86      */
87     @SystemApi
isPublicBroadcast()88     public boolean isPublicBroadcast() {
89         return mIsPublicBroadcast;
90     }
91 
92     /**
93      * Return the broadcast code for this Broadcast Group.
94      *
95      * @return Broadcast name for this Broadcast Group, null if no name provided
96      * @hide
97      */
98     @SystemApi
99     @Nullable
getBroadcastName()100     public String getBroadcastName() {
101         return mBroadcastName;
102     }
103 
104     /**
105      * Get the Broadcast Code currently set for this broadcast group.
106      *
107      * <p>Only needed when encryption is enabled
108      *
109      * <p>As defined in Volume 3, Part C, Section 3.2.6 of Bluetooth Core Specification, Version
110      * 5.3, Broadcast Code is used to encrypt a broadcast audio stream.
111      *
112      * <p>It must be a UTF-8 string that has at least 4 octets and should not exceed 16 octets.
113      *
114      * @return Broadcast Code currently set for this broadcast group, null if code is not required
115      *     or code is currently unknown
116      * @hide
117      */
118     @SystemApi
119     @Nullable
getBroadcastCode()120     public byte[] getBroadcastCode() {
121         return mBroadcastCode;
122     }
123 
124     /**
125      * Get public broadcast metadata for this Broadcast Group.
126      *
127      * @return public broadcast metadata for this Broadcast Group, null if no public metadata exists
128      * @hide
129      */
130     @SystemApi
131     @Nullable
getPublicBroadcastMetadata()132     public BluetoothLeAudioContentMetadata getPublicBroadcastMetadata() {
133         return mPublicBroadcastMetadata;
134     }
135 
136     /**
137      * Get available subgroup settings in the broadcast group.
138      *
139      * @return list of subgroup settings in the broadcast group
140      * @hide
141      */
142     @SystemApi
143     @NonNull
getSubgroupSettings()144     public List<BluetoothLeBroadcastSubgroupSettings> getSubgroupSettings() {
145         return mSubgroupSettings;
146     }
147 
148     /**
149      * {@inheritDoc}
150      *
151      * @hide
152      */
153     @Override
describeContents()154     public int describeContents() {
155         return 0;
156     }
157 
158     /**
159      * {@inheritDoc}
160      *
161      * @hide
162      */
163     @Override
writeToParcel(Parcel out, int flags)164     public void writeToParcel(Parcel out, int flags) {
165         out.writeBoolean(mIsPublicBroadcast);
166         BluetoothUtils.writeStringToParcel(out, mBroadcastName);
167         out.writeByteArray(mBroadcastCode);
168         out.writeTypedObject(mPublicBroadcastMetadata, 0);
169         out.writeTypedList(mSubgroupSettings);
170     }
171 
172     /**
173      * A {@link Parcelable.Creator} to create {@link BluetoothLeBroadcastSettings} from parcel.
174      *
175      * @hide
176      */
177     @SystemApi @NonNull
178     public static final Creator<BluetoothLeBroadcastSettings> CREATOR =
179             new Creator<>() {
180                 public @NonNull BluetoothLeBroadcastSettings createFromParcel(@NonNull Parcel in) {
181                     Builder builder = new Builder();
182                     builder.setPublicBroadcast(in.readBoolean());
183                     builder.setBroadcastName(in.readString());
184                     byte[] broadcastCode = in.createByteArray();
185                     builder.setBroadcastCode(broadcastCode);
186                     builder.setPublicBroadcastMetadata(
187                             in.readTypedObject(BluetoothLeAudioContentMetadata.CREATOR));
188                     final List<BluetoothLeBroadcastSubgroupSettings> subgroupSettings =
189                             new ArrayList<>();
190                     in.readTypedList(
191                             subgroupSettings, BluetoothLeBroadcastSubgroupSettings.CREATOR);
192                     for (BluetoothLeBroadcastSubgroupSettings setting : subgroupSettings) {
193                         builder.addSubgroupSettings(setting);
194                     }
195                     return builder.build();
196                 }
197 
198                 public @NonNull BluetoothLeBroadcastSettings[] newArray(int size) {
199                     return new BluetoothLeBroadcastSettings[size];
200                 }
201             };
202 
203     /**
204      * Builder for {@link BluetoothLeBroadcastSettings}.
205      *
206      * @hide
207      */
208     @SystemApi
209     public static final class Builder {
210         private boolean mIsPublicBroadcast = false;
211         private String mBroadcastName = null;
212         private byte[] mBroadcastCode = null;
213         private BluetoothLeAudioContentMetadata mPublicBroadcastMetadata = null;
214         private List<BluetoothLeBroadcastSubgroupSettings> mSubgroupSettings = new ArrayList<>();
215 
216         /**
217          * Create an empty builder.
218          *
219          * @hide
220          */
221         @SystemApi
Builder()222         public Builder() {}
223 
224         /**
225          * Create a builder with copies of information from original object.
226          *
227          * @param original original object
228          * @hide
229          */
230         @SystemApi
Builder(@onNull BluetoothLeBroadcastSettings original)231         public Builder(@NonNull BluetoothLeBroadcastSettings original) {
232             mIsPublicBroadcast = original.isPublicBroadcast();
233             mBroadcastName = original.getBroadcastName();
234             mBroadcastCode = original.getBroadcastCode();
235             mPublicBroadcastMetadata = original.getPublicBroadcastMetadata();
236             mSubgroupSettings = original.getSubgroupSettings();
237         }
238 
239         /**
240          * Set whether the Public Broadcast is on for this broadcast group.
241          *
242          * @param isPublicBroadcast whether the Public Broadcast is enabled
243          * @return this builder
244          * @hide
245          */
246         @SystemApi
247         @NonNull
setPublicBroadcast(boolean isPublicBroadcast)248         public Builder setPublicBroadcast(boolean isPublicBroadcast) {
249             mIsPublicBroadcast = isPublicBroadcast;
250             return this;
251         }
252 
253         /**
254          * Set broadcast name for the broadcast group.
255          *
256          * <p>As defined in Public Broadcast Profile V1.0, section 5.1. Broadcast_Name AD Type is a
257          * UTF-8 encoded string containing a minimum of 4 characters and a maximum of 32
258          * human-readable characters.
259          *
260          * @param broadcastName Broadcast name for this broadcast group, null if no name provided
261          * @throws IllegalArgumentException if name is non-null and its length is less than 4
262          *     characters or greater than 32 characters
263          * @return this builder
264          * @hide
265          */
266         @SystemApi
267         @NonNull
setBroadcastName(@ullable String broadcastName)268         public Builder setBroadcastName(@Nullable String broadcastName) {
269             if (broadcastName != null
270                     && ((broadcastName.length() > 32) || (broadcastName.length() < 4))) {
271                 throw new IllegalArgumentException("Invalid broadcast name length");
272             }
273             mBroadcastName = broadcastName;
274             return this;
275         }
276 
277         /**
278          * Set the Broadcast Code currently set for this broadcast group.
279          *
280          * <p>Only needed when encryption is enabled As defined in Volume 3, Part C, Section 3.2.6
281          * of Bluetooth Core Specification, Version 5.3, Broadcast Code is used to encrypt a
282          * broadcast audio stream. It must be a UTF-8 string that has at least 4 octets and should
283          * not exceed 16 octets.
284          *
285          * @param broadcastCode Broadcast Code for this broadcast group, null if code is not
286          *     required for non-encrypted broadcast
287          * @throws IllegalArgumentException if name is non-null and its length is less than 4
288          *     characters or greater than 16 characters
289          * @return this builder
290          * @hide
291          */
292         @SystemApi
293         @NonNull
setBroadcastCode(@ullable byte[] broadcastCode)294         public Builder setBroadcastCode(@Nullable byte[] broadcastCode) {
295             if (broadcastCode != null
296                     && ((broadcastCode.length > 16) || (broadcastCode.length < 4))) {
297                 throw new IllegalArgumentException("Invalid broadcast code length");
298             }
299             mBroadcastCode = broadcastCode;
300             return this;
301         }
302 
303         /**
304          * Set public broadcast metadata for this Broadcast Group. PBS should include the
305          * Program_Info length-type-value (LTV) structure metadata
306          *
307          * @param publicBroadcastMetadata public broadcast metadata for this Broadcast Group, null
308          *     if no public meta data provided
309          * @return this builder
310          * @hide
311          */
312         @SystemApi
313         @NonNull
setPublicBroadcastMetadata( @ullable BluetoothLeAudioContentMetadata publicBroadcastMetadata)314         public Builder setPublicBroadcastMetadata(
315                 @Nullable BluetoothLeAudioContentMetadata publicBroadcastMetadata) {
316             mPublicBroadcastMetadata = publicBroadcastMetadata;
317             return this;
318         }
319 
320         /**
321          * Add a subgroup settings to the broadcast group.
322          *
323          * @param subgroupSettings contains subgroup's setting data
324          * @return this builder
325          * @hide
326          */
327         @SystemApi
328         @NonNull
addSubgroupSettings( @onNull BluetoothLeBroadcastSubgroupSettings subgroupSettings)329         public Builder addSubgroupSettings(
330                 @NonNull BluetoothLeBroadcastSubgroupSettings subgroupSettings) {
331             requireNonNull(subgroupSettings);
332             mSubgroupSettings.add(subgroupSettings);
333             return this;
334         }
335 
336         /**
337          * Clear subgroup settings list so that one can reset the builder
338          *
339          * @return this builder
340          * @hide
341          */
342         @SystemApi
343         @NonNull
clearSubgroupSettings()344         public Builder clearSubgroupSettings() {
345             mSubgroupSettings.clear();
346             return this;
347         }
348 
349         /**
350          * Build {@link BluetoothLeBroadcastSettings}.
351          *
352          * @return {@link BluetoothLeBroadcastSettings}
353          * @throws IllegalArgumentException if the object cannot be built
354          * @hide
355          */
356         @SystemApi
357         @NonNull
build()358         public BluetoothLeBroadcastSettings build() {
359             if (mSubgroupSettings.isEmpty()) {
360                 throw new IllegalArgumentException("Must contain at least one subgroup");
361             }
362             return new BluetoothLeBroadcastSettings(
363                     mIsPublicBroadcast,
364                     mBroadcastName,
365                     mBroadcastCode,
366                     mPublicBroadcastMetadata,
367                     mSubgroupSettings);
368         }
369     }
370 }
371