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