608 lines
22 KiB
Java
608 lines
22 KiB
Java
/*
|
|
* 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.Arrays;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* The {@link BluetoothLeBroadcastReceiveState} is used by the BASS server to expose information
|
|
* about a Broadcast Source.
|
|
*
|
|
* <p>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;
|
|
|
|
private static String paSyncStateToString(int paSyncState) {
|
|
switch (paSyncState) {
|
|
case 0x00:
|
|
return "Not synchronized to PA: [" + Integer.toString(paSyncState) + "]";
|
|
case 0x01:
|
|
return "SyncInfo Request: [" + Integer.toString(paSyncState) + "]";
|
|
case 0x02:
|
|
return "Synchronized to PA: [" + Integer.toString(paSyncState) + "]";
|
|
case 0x03:
|
|
return "Failed to synchronize to PA: [" + Integer.toString(paSyncState) + "]";
|
|
case 0x04:
|
|
return "No PAST: [" + Integer.toString(paSyncState) + "]";
|
|
default:
|
|
return "RFU: [" + Integer.toString(paSyncState) + "]";
|
|
}
|
|
}
|
|
|
|
private static String bigEncryptionStateToString(int bigEncryptionState) {
|
|
switch (bigEncryptionState) {
|
|
case 0x00:
|
|
return "Not encrypted: [" + Integer.toString(bigEncryptionState) + "]";
|
|
case 0x01:
|
|
return "Broadcast_Code required: [" + Integer.toString(bigEncryptionState) + "]";
|
|
case 0x02:
|
|
return "Decrypting: [" + Integer.toString(bigEncryptionState) + "]";
|
|
case 0x03:
|
|
return "Bad_Code (incorrect encryption key): ["
|
|
+ Integer.toString(bigEncryptionState)
|
|
+ "]";
|
|
default:
|
|
return "RFU: [" + Integer.toString(bigEncryptionState) + "]";
|
|
}
|
|
}
|
|
|
|
private static String bisSyncStateToString(Long bisSyncState, int bisSyncStateIndex) {
|
|
if (bisSyncState == 0) {
|
|
return "Not synchronized to BIS_index["
|
|
+ Integer.toString(bisSyncStateIndex)
|
|
+ "]: ["
|
|
+ String.valueOf(bisSyncState)
|
|
+ "]";
|
|
} else if (bisSyncState > 0 && bisSyncState < 0xFFFFFFFF) {
|
|
return "Synchronized to BIS_index["
|
|
+ Integer.toString(bisSyncStateIndex)
|
|
+ "]: ["
|
|
+ String.valueOf(bisSyncState)
|
|
+ "]";
|
|
} else if (bisSyncState == 0xFFFFFFFF) {
|
|
return "Failed to sync to BIG: [" + String.valueOf(bisSyncState) + "]";
|
|
} else {
|
|
return "[" + String.valueOf(bisSyncState) + "]";
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Constructor to create a read-only {@link BluetoothLeBroadcastReceiveState} instance.
|
|
*
|
|
* @throws NullPointerException if sourceDevice, bisSyncState, or subgroupMetadata is null
|
|
* @throws IllegalArgumentException if sourceID is not [0, 0xFF] or if sourceAddressType is
|
|
* invalid or if bisSyncState.size() != numSubgroups or if subgroupMetadata.size() !=
|
|
* numSubgroups or if paSyncState or bigEncryptionState is not recognized bye IntDef
|
|
* @hide
|
|
*/
|
|
public BluetoothLeBroadcastReceiveState(
|
|
@IntRange(from = 0x00, to = 0xFF) int sourceId,
|
|
@BluetoothDevice.AddressType int sourceAddressType,
|
|
@NonNull BluetoothDevice sourceDevice,
|
|
int sourceAdvertisingSid,
|
|
int broadcastId,
|
|
@PaSyncState int paSyncState,
|
|
@BigEncryptionState int bigEncryptionState,
|
|
byte[] badCode,
|
|
@IntRange(from = 0x00) int numSubgroups,
|
|
@NonNull List<Long> bisSyncState,
|
|
@NonNull List<BluetoothLeAudioContentMetadata> subgroupMetadata) {
|
|
if (sourceId < 0x00 || sourceId > 0xFF) {
|
|
throw new IllegalArgumentException(
|
|
"sourceId " + sourceId + " does not fall between 0x00 and 0xFF");
|
|
}
|
|
Objects.requireNonNull(sourceDevice, "sourceDevice cannot be null");
|
|
if (sourceAddressType == BluetoothDevice.ADDRESS_TYPE_UNKNOWN) {
|
|
throw new IllegalArgumentException("sourceAddressType cannot be ADDRESS_TYPE_UNKNOWN");
|
|
}
|
|
if (sourceAddressType != BluetoothDevice.ADDRESS_TYPE_RANDOM
|
|
&& sourceAddressType != BluetoothDevice.ADDRESS_TYPE_PUBLIC) {
|
|
throw new IllegalArgumentException(
|
|
"sourceAddressType " + sourceAddressType + " is invalid");
|
|
}
|
|
Objects.requireNonNull(bisSyncState, "bisSyncState cannot be null");
|
|
if (bisSyncState.size() != numSubgroups) {
|
|
throw new IllegalArgumentException(
|
|
"bisSyncState.size() "
|
|
+ bisSyncState.size()
|
|
+ " must be equal to numSubgroups "
|
|
+ numSubgroups);
|
|
}
|
|
Objects.requireNonNull(subgroupMetadata, "subgroupMetadata cannot be null");
|
|
if (subgroupMetadata.size() != numSubgroups) {
|
|
throw new IllegalArgumentException(
|
|
"subgroupMetadata.size() "
|
|
+ subgroupMetadata.size()
|
|
+ " must be equal to numSubgroups "
|
|
+ numSubgroups);
|
|
}
|
|
if (paSyncState != PA_SYNC_STATE_IDLE
|
|
&& paSyncState != PA_SYNC_STATE_SYNCINFO_REQUEST
|
|
&& paSyncState != PA_SYNC_STATE_SYNCHRONIZED
|
|
&& paSyncState != PA_SYNC_STATE_FAILED_TO_SYNCHRONIZE
|
|
&& paSyncState != PA_SYNC_STATE_NO_PAST
|
|
&& paSyncState != PA_SYNC_STATE_INVALID) {
|
|
throw new IllegalArgumentException("unrecognized paSyncState " + paSyncState);
|
|
}
|
|
if (bigEncryptionState != BIG_ENCRYPTION_STATE_NOT_ENCRYPTED
|
|
&& bigEncryptionState != BIG_ENCRYPTION_STATE_CODE_REQUIRED
|
|
&& bigEncryptionState != BIG_ENCRYPTION_STATE_DECRYPTING
|
|
&& bigEncryptionState != BIG_ENCRYPTION_STATE_BAD_CODE
|
|
&& bigEncryptionState != BIG_ENCRYPTION_STATE_INVALID) {
|
|
throw new IllegalArgumentException(
|
|
"unrecognized bigEncryptionState " + bigEncryptionState);
|
|
}
|
|
if (badCode != null && badCode.length != 16) {
|
|
throw new IllegalArgumentException(
|
|
"badCode must be 16 bytes long of null, but is "
|
|
+ badCode.length
|
|
+ " + bytes long");
|
|
}
|
|
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
|
|
*
|
|
* <p>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
|
|
*
|
|
* <p>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)
|
|
*
|
|
* <p>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
|
|
*
|
|
* <p>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])
|
|
*
|
|
* <p>For example, if (BisSyncState & 0b1 << 5) != 0, BIS 5 is synchronized between source and
|
|
* sync
|
|
*
|
|
* <p>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
|
|
*
|
|
* <p>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);
|
|
}
|
|
|
|
/**
|
|
* {@inheritDoc}
|
|
*
|
|
* @hide
|
|
*/
|
|
@Override
|
|
public String toString() {
|
|
String receiveState =
|
|
("Receiver state: "
|
|
+ "\n Source ID:"
|
|
+ mSourceId
|
|
+ "\n Source Address Type:"
|
|
+ (int) mSourceAddressType
|
|
+ "\n Source Address:"
|
|
+ mSourceDevice.toString()
|
|
+ "\n Source Adv SID:"
|
|
+ mSourceAdvertisingSid
|
|
+ "\n Broadcast ID:"
|
|
+ mBroadcastId
|
|
+ "\n PA Sync State:"
|
|
+ paSyncStateToString(mPaSyncState)
|
|
+ "\n BIG Encryption Status:"
|
|
+ bigEncryptionStateToString(mBigEncryptionState)
|
|
+ "\n Bad Broadcast Code:"
|
|
+ Arrays.toString(mBadCode)
|
|
+ "\n Number Of Subgroups:"
|
|
+ mNumSubgroups);
|
|
for (int i = 0; i < mNumSubgroups; i++) {
|
|
receiveState +=
|
|
("\n Subgroup index:"
|
|
+ i
|
|
+ "\n BIS Sync State:"
|
|
+ bisSyncStateToString(mBisSyncState.get(i), i))
|
|
+ "\n Metadata:"
|
|
+ "\n ProgramInfo:"
|
|
+ mSubgroupMetadata.get(i).getProgramInfo()
|
|
+ "\n Language:"
|
|
+ mSubgroupMetadata.get(i).getLanguage()
|
|
+ "\n RawData:"
|
|
+ Arrays.toString(mSubgroupMetadata.get(i).getRawMetadata());
|
|
}
|
|
return receiveState;
|
|
}
|
|
|
|
/**
|
|
* A {@link Parcelable.Creator} to create {@link BluetoothLeBroadcastReceiveState} from parcel.
|
|
*
|
|
* @hide
|
|
*/
|
|
@SystemApi @NonNull
|
|
public static final Creator<BluetoothLeBroadcastReceiveState> CREATOR =
|
|
new Creator<>() {
|
|
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];
|
|
}
|
|
};
|
|
}
|