summaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java
diff options
context:
space:
mode:
authorJack He <siyuanh@google.com>2022-02-03 07:30:59 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-02-03 07:30:59 +0000
commit602cb15f1577a9d932c514ff6d472ec15dc3f1ad (patch)
tree4a1ebd19d55f85b3292cbb1846f2f259d5bbf6b5 /framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java
parentc12ba609a8d7dc05ef4aa0b80c813bd5d86caf23 (diff)
parent0dc9bbcf7f437a28edc26a5fa368c4e4021f6a62 (diff)
Introduce LE audio broadcast system APIs am: a014314c94 am: de7f1f372c am: 0dc9bbcf7f
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Bluetooth/+/1959800 Change-Id: I1bba0232e4c5e3bbcbd5a2305068909d06f3488b
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java449
1 files changed, 449 insertions, 0 deletions
diff --git a/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java b/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java
new file mode 100644
index 0000000000..bab17ee797
--- /dev/null
+++ b/framework/java/android/bluetooth/BluetoothLeBroadcastReceiveState.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright 2022 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;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The {@link BluetoothLeBroadcastReceiveState} is used by the BASS server to expose information
+ * about a Broadcast Source.
+ *
+ * It represents the current synchronization state of the server to
+ * a PA and/or a BIG containing one or more subgroups containing one or more BISes
+ * transmitted by that Broadcast Source. The Broadcast Receive State characteristic is also
+ * used to inform clients whether the server has detected that the BIS is encrypted, whether
+ * the server requires a Broadcast_Code, and whether the server is decrypting the BIS.
+ *
+ * @hide
+ */
+@SystemApi
+public final class BluetoothLeBroadcastReceiveState implements Parcelable {
+ /**
+ * Periodic Advertising Synchronization state.
+ *
+ * <p>Periodic Advertising (PA) enables the LE Audio Broadcast Assistant to discover broadcast
+ * audio streams as well as the audio stream configuration on behalf of an LE Audio Broadcast
+ * Sink. This information can then be transferred to the LE Audio Broadcast Sink using the
+ * Periodic Advertising Synchronization Transfer (PAST) procedure.
+ *
+ * @hide
+ */
+ @IntDef(prefix = "PA_SYNC_STATE_",
+ value = {
+ PA_SYNC_STATE_IDLE,
+ PA_SYNC_STATE_SYNCINFO_REQUEST,
+ PA_SYNC_STATE_SYNCHRONIZED,
+ PA_SYNC_STATE_FAILED_TO_SYNCHRONIZE,
+ PA_SYNC_STATE_NO_PAST
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PaSyncState {}
+
+ /**
+ * Indicates that the Broadcast Sink is not synchronized with the Periodic Advertisements (PA)
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int PA_SYNC_STATE_IDLE = 0;
+
+ /**
+ * Indicates that the Broadcast Sink requested the Broadcast Assistant to synchronize with the
+ * Periodic Advertisements (PA).
+ *
+ * <p>This is also known as scan delegation or scan offloading.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int PA_SYNC_STATE_SYNCINFO_REQUEST = 1;
+
+ /**
+ * Indicates that the Broadcast Sink is synchronized with the Periodic Advertisements (PA).
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int PA_SYNC_STATE_SYNCHRONIZED = 2;
+
+ /**
+ * Indicates that the Broadcast Sink was unable to synchronize with the Periodic Advertisements
+ * (PA).
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int PA_SYNC_STATE_FAILED_TO_SYNCHRONIZE = 3;
+
+ /**
+ * Indicates that the Broadcast Sink should be synchronized with the Periodic Advertisements
+ * (PA) using the Periodic Advertisements Synchronization Transfer (PAST) procedure.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int PA_SYNC_STATE_NO_PAST = 4;
+
+ /**
+ * Indicates that the Broadcast Sink synchronization state is invalid.
+ *
+ * @hide
+ */
+ public static final int PA_SYNC_STATE_INVALID = 0xFFFF;
+
+ /** @hide */
+ @IntDef(
+ prefix = "BIG_ENCRYPTION_STATE_",
+ value = {
+ BIG_ENCRYPTION_STATE_NOT_ENCRYPTED,
+ BIG_ENCRYPTION_STATE_CODE_REQUIRED,
+ BIG_ENCRYPTION_STATE_DECRYPTING,
+ BIG_ENCRYPTION_STATE_BAD_CODE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface BigEncryptionState {}
+
+ /**
+ * Indicates that the Broadcast Sink is synchronized with an unencrypted audio stream from a
+ * Broadcast Source
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int BIG_ENCRYPTION_STATE_NOT_ENCRYPTED = 0;
+
+ /**
+ * Indicates that the Broadcast Sink needs a Broadcast Code to synchronize with an audio stream
+ * from a Broadcast Source, which was not provided when the audio stream from the Broadcast
+ * Source was added.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int BIG_ENCRYPTION_STATE_CODE_REQUIRED = 1;
+
+ /**
+ * Indicates that the Broadcast Sink is synchronized with an encrypted audio stream from a
+ * Broadcast Source.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int BIG_ENCRYPTION_STATE_DECRYPTING = 2;
+
+ /**
+ * Indicates that the Broadcast Sink is unable to decrypt an audio stream from a Broadcast
+ * Source due to an incorrect Broadcast Code.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int BIG_ENCRYPTION_STATE_BAD_CODE = 3;
+
+ /**
+ * Indicates that the Broadcast Sink encryption state is invalid.
+ *
+ * @hide
+ */
+ public static final int BIG_ENCRYPTION_STATE_INVALID = 0xFFFF;
+
+ private final int mSourceId;
+ private final @BluetoothDevice.AddressType int mSourceAddressType;
+ private final BluetoothDevice mSourceDevice;
+ private final int mSourceAdvertisingSid;
+ private final int mBroadcastId;
+ private final @PaSyncState int mPaSyncState;
+ private final @BigEncryptionState int mBigEncryptionState;
+ private final byte[] mBadCode;
+ private final int mNumSubgroups;
+ private final List<Long> mBisSyncState;
+ private final List<BluetoothLeAudioContentMetadata> mSubgroupMetadata;
+
+ /**
+ * Constructor to create a read-only {@link BluetoothLeBroadcastReceiveState} instance.
+ *
+ * @hide
+ */
+ public BluetoothLeBroadcastReceiveState(int sourceId, int sourceAddressType,
+ BluetoothDevice sourceDevice, int sourceAdvertisingSid, int broadcastId,
+ int paSyncState, int bigEncryptionState, byte[] badCode, int numSubgroups,
+ List<Long> bisSyncState,
+ List<BluetoothLeAudioContentMetadata> subgroupMetadata) {
+ mSourceId = sourceId;
+ mSourceAddressType = sourceAddressType;
+ mSourceDevice = sourceDevice;
+ mSourceAdvertisingSid = sourceAdvertisingSid;
+ mBroadcastId = broadcastId;
+ mPaSyncState = paSyncState;
+ mBigEncryptionState = bigEncryptionState;
+ mBadCode = badCode;
+ mNumSubgroups = numSubgroups;
+ mBisSyncState = bisSyncState;
+ mSubgroupMetadata = subgroupMetadata;
+ }
+
+ /**
+ * Get the source ID assigned by the BASS server
+ *
+ * Shall be unique for each instance of the Broadcast Receive State characteristic exposed by
+ * the server
+ *
+ * @return source ID assigned by the BASS server
+ * @hide
+ */
+ @SystemApi
+ public @IntRange(from = 0x00, to = 0xFF) int getSourceId() {
+ return mSourceId;
+ }
+
+ /**
+ * Get the address type of the Broadcast Source
+ *
+ * Can be either {@link BluetoothDevice#ADDRESS_TYPE_PUBLIC} or
+ * {@link BluetoothDevice#ADDRESS_TYPE_RANDOM
+ *
+ * @return address type of the Broadcast Source
+ * @hide
+ */
+ @SystemApi
+ public @BluetoothDevice.AddressType int getSourceAddressType() {
+ return mSourceAddressType;
+ }
+
+ /**
+ * Get the MAC address of the Broadcast Source, which can be Public Device Address,
+ * Random Device Address, Public Identity Address or Random (static) Identity Address
+ *
+ * @return MAC address of the Broadcast Source
+ * @hide
+ */
+ @SystemApi
+ public @NonNull BluetoothDevice getSourceDevice() {
+ return mSourceDevice;
+ }
+
+ /**
+ * Get Advertising_SID subfield of the ADI field of the AUX_ADV_IND PDU or the
+ * LL_PERIODIC_SYNC_IND containing the SyncInfo that points to the PA transmitted by the
+ * Broadcast Source.
+ *
+ * @return 1-byte long Advertising_SID of the Broadcast Source
+ * @hide
+ */
+ @SystemApi
+ public int getSourceAdvertisingSid() {
+ return mSourceAdvertisingSid;
+ }
+
+ /**
+ * Broadcast_ID of the Broadcast Source
+ *
+ * @return 3-byte long Broadcast_ID of the Broadcast Source
+ * @hide
+ */
+ @SystemApi
+ public int getBroadcastId() {
+ return mBroadcastId;
+ }
+
+ /**
+ * Get the Periodic Advertisement synchronization state between the Broadcast Sink and the
+ * Broadcast source
+ *
+ * Possible values are {@link #PA_SYNC_STATE_IDLE}, {@link #PA_SYNC_STATE_SYNCINFO_REQUEST},
+ * {@link #PA_SYNC_STATE_SYNCHRONIZED}, {@link #PA_SYNC_STATE_FAILED_TO_SYNCHRONIZE},
+ * {@link #PA_SYNC_STATE_NO_PAST}
+ *
+ * @return Periodic Advertisement synchronization state
+ * @hide
+ */
+ @SystemApi
+ public @PaSyncState int getPaSyncState() {
+ return mPaSyncState;
+ }
+
+ /**
+ * Get the encryption state of a Broadcast Isochronous Group (BIG)
+ *
+ * Possible values are {@link #BIG_ENCRYPTION_STATE_NOT_ENCRYPTED},
+ * {@link #BIG_ENCRYPTION_STATE_CODE_REQUIRED}, {@link #BIG_ENCRYPTION_STATE_DECRYPTING},
+ * {@link #BIG_ENCRYPTION_STATE_DECRYPTING}, and {@link #BIG_ENCRYPTION_STATE_BAD_CODE}
+ *
+ * @return encryption state of a Broadcast Isochronous Group (BIG)
+ * @hide
+ */
+ @SystemApi
+ public @BigEncryptionState int getBigEncryptionState() {
+ return mBigEncryptionState;
+ }
+
+ /**
+ * If {@link #getBigEncryptionState()} returns {@link #BIG_ENCRYPTION_STATE_BAD_CODE}, this
+ * method returns the value of the incorrect 16-octet Broadcast Code that fails to decrypt
+ * an audio stream from a Broadcast Source.
+ *
+ * @return 16-octet Broadcast Code, or null if {@link #getBigEncryptionState()} does not return
+ * {@link #BIG_ENCRYPTION_STATE_BAD_CODE}
+ * @hide
+ */
+ @SystemApi
+ public @Nullable byte[] getBadCode() {
+ return mBadCode;
+ }
+
+ /**
+ * Get number of Broadcast subgroups being added to this sink
+ *
+ * @return number of Broadcast subgroups being added to this sink
+ */
+ public int getNumSubgroups() {
+ return mNumSubgroups;
+ }
+
+ /**
+ * Get a list of bitfield on whether a Broadcast Isochronous Stream (BIS) is synchronized
+ * between the sink and source
+ *
+ * The number of items in the returned list is the same as {@link #getNumSubgroups()}. For each
+ * subgroup, at most 31 BISes are available and their synchronization state is indicated by its
+ * bit value at the particular offset (i.e. Bit 0-30 = BIS_index[1-31])
+ *
+ * For example, if (BisSyncState & 0b1 << 5) != 0, BIS 5 is synchronized between source and sync
+ *
+ * There is a special case, 0xFFFFFFFF to indicate Broadcast Sink failed to synchronize to
+ * a particular subgroup
+ *
+ * @return a list of bitfield on whether a Broadcast Isochronous Stream (BIS) is synchronized
+ * between the sink and source
+ * @hide
+ */
+ @SystemApi
+ public @NonNull List<Long> getBisSyncState() {
+ return mBisSyncState;
+ }
+
+ /**
+ * Get metadata for every subgroup added to this Broadcast Sink
+ *
+ * The number of items in the returned list is the same as {@link #getNumSubgroups()}.
+ *
+ * @return metadata for every subgroup added to this Broadcast Sink
+ * @hide
+ */
+ @SystemApi
+ public @NonNull List<BluetoothLeAudioContentMetadata> getSubgroupMetadata() {
+ return mSubgroupMetadata;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mSourceId);
+ out.writeInt(mSourceAddressType);
+ out.writeTypedObject(mSourceDevice, 0);
+ out.writeInt(mSourceAdvertisingSid);
+ out.writeInt(mBroadcastId);
+ out.writeInt(mPaSyncState);
+ out.writeInt(mBigEncryptionState);
+
+ if (mBadCode != null) {
+ out.writeInt(mBadCode.length);
+ out.writeByteArray(mBadCode);
+ } else {
+ // -1 indicates that there is no "bad broadcast code"
+ out.writeInt(-1);
+ }
+ out.writeInt(mNumSubgroups);
+ out.writeList(mBisSyncState);
+ out.writeTypedList(mSubgroupMetadata);
+ }
+
+ /**
+ * A {@link Parcelable.Creator} to create {@link BluetoothLeBroadcastReceiveState} from parcel.
+ * @hide
+ */
+ @SystemApi
+ public static final @NonNull Parcelable.Creator<BluetoothLeBroadcastReceiveState> CREATOR =
+ new Parcelable.Creator<BluetoothLeBroadcastReceiveState>() {
+ public @NonNull BluetoothLeBroadcastReceiveState createFromParcel(
+ @NonNull Parcel in) {
+ final int sourceId = in.readInt();
+ final int sourceAddressType = in.readInt();
+ final BluetoothDevice sourceDevice =
+ in.readTypedObject(BluetoothDevice.CREATOR);
+ final int sourceAdvertisingSid = in.readInt();
+ final int broadcastId = in.readInt();
+ final int paSyncState = in.readInt();
+ final int bigEncryptionState = in.readInt();
+ final int badCodeLen = in.readInt();
+ byte[] badCode = null;
+
+ if (badCodeLen != -1) {
+ badCode = new byte[badCodeLen];
+ if (badCodeLen > 0) {
+ in.readByteArray(badCode);
+ }
+ }
+ final byte numSubGroups = in.readByte();
+ final List<Long> bisSyncState =
+ in.readArrayList(Long.class.getClassLoader(), Long.class);
+ final List<BluetoothLeAudioContentMetadata> subgroupMetadata =
+ new ArrayList<>();
+ in.readTypedList(subgroupMetadata, BluetoothLeAudioContentMetadata.CREATOR);
+
+ return new BluetoothLeBroadcastReceiveState(
+ sourceId,
+ sourceAddressType,
+ sourceDevice,
+ sourceAdvertisingSid,
+ broadcastId,
+ paSyncState,
+ bigEncryptionState,
+ badCode,
+ numSubGroups,
+ bisSyncState,
+ subgroupMetadata);
+ }
+
+ public @NonNull BluetoothLeBroadcastReceiveState[] newArray(int size) {
+ return new BluetoothLeBroadcastReceiveState[size];
+ }
+ };
+}