| /****************************************************************************** |
| * |
| * Copyright 2021 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.bluetooth.BluetoothAdapter; |
| import android.bluetooth.BluetoothDevice; |
| import android.bluetooth.IBluetoothGatt; |
| import android.bluetooth.IBluetoothManager; |
| import java.lang.annotation.RetentionPolicy; |
| import java.lang.annotation.Retention; |
| import android.annotation.IntDef; |
| import android.compat.annotation.UnsupportedAppUsage; |
| |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.os.Handler; |
| import android.os.Looper; |
| import android.os.RemoteException; |
| import android.util.Log; |
| import java.util.Objects; |
| import android.util.Log; |
| import java.util.List; |
| import java.util.ArrayList; |
| import java.util.IdentityHashMap; |
| import java.util.Map; |
| import java.util.HashMap; |
| |
| /** |
| * This class provides methods to get various information of Broadcast |
| * source information stored in remote. Users can call get/set methods |
| * enquire the required information |
| * |
| * <p>This also acts as general data structure for updating the Broadcast |
| * source information |
| * This class is used to input the User provided data for below operations |
| * {@link BleBroadcastAudioScanAssistManager#addBroadcastSource}, |
| * {@link BleBroadcastAudioScanAssistManager#updateBroadcastSource} and |
| * {@link BleBroadcastAudioScanAssistManager#setBroadcastCode} |
| * |
| * <p>This is also used to pack all Broadcast source information as part of {@link #ACTION_BROADCAST_RECEIVER_STATE} |
| * Intent. User can retrive the {@link BleBroadcastSourceInfo} using {@link BleBroadcastSourceInfo#EXTRA_RECEIVER_STATE} |
| * extra field |
| * @hide |
| */ |
| public final class BleBroadcastSourceInfo implements Parcelable { |
| |
| private static final String TAG = "BleBroadcastSourceInfo"; |
| private static final boolean BASS_DBG = Log.isLoggable(TAG, Log.VERBOSE); |
| |
| /** @hide |
| * @deprecated |
| */ |
| @Deprecated |
| @IntDef(prefix = "BROADCAST_ASSIST_ADDRESS_TYPE_", value = { |
| BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC, |
| BROADCAST_ASSIST_ADDRESS_TYPE_RANDOM |
| }) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface BroadcastAssistAddressType {} |
| |
| /** |
| * Address Type of the LE Broadcast Audio Source Device |
| * Specifies whether LE Broadcast Audio Source device using public OR |
| * random address for the LE Audio broadcasts |
| * |
| * @deprecated |
| */ |
| @Deprecated |
| public static final int BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC = 0; |
| /** |
| * Address Type of the LE Broadcast Audio Source Device |
| * Specifies whether LE Broadcast Audio Source device using public OR |
| * random address for the LE Audio broadcasts |
| * |
| * @deprecated |
| */ |
| @Deprecated |
| public static final int BROADCAST_ASSIST_ADDRESS_TYPE_RANDOM = 1; |
| /** |
| * Address Type of the LE Broadcast Audio Source Device |
| * Specifies whether LE Broadcast Audio Source device using public PR |
| * random address for the LE Audio broadcasts |
| * |
| * @deprecated |
| */ |
| @Deprecated |
| public static final int BROADCAST_ASSIST_ADDRESS_TYPE_INVALID = 0xFFFF; |
| |
| /** @hide */ |
| @IntDef(prefix = "BROADCAST_ASSIST_PA_SYNC_STATE_", value = { |
| BROADCAST_ASSIST_PA_SYNC_STATE_IDLE, |
| BROADCAST_ASSIST_PA_SYNC_STATE_SYNCINFO_REQ, |
| BROADCAST_ASSIST_PA_SYNC_STATE_IN_SYNC, |
| BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_FAIL, |
| BROADCAST_ASSIST_PA_SYNC_STATE_NO_PAST |
| }) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface BroadcastAssistMetadataSyncState {} |
| |
| /** |
| * Meta data Sync State |
| * Broadcast receiver sync state w.r.t PA. State IDLE specifies that broadcast |
| * receiver is not able to sync the Metada/PA |
| */ |
| public static final int BROADCAST_ASSIST_PA_SYNC_STATE_IDLE = 0; |
| /** |
| * Meta data Sync State |
| * Broadcast receiver sync state w.r.t PA. State SYNCINFO REQ specifies that broadcast |
| * receiver requesting for SYNCINFO from the Scan Offloader to synchronie |
| * to Metadata/PA |
| */ |
| public static final int BROADCAST_ASSIST_PA_SYNC_STATE_SYNCINFO_REQ = 1; |
| /** |
| * Meta data Sync State |
| * Broadcast receiver sync state w.r.t PA. State INSYNC specifies that broadcast |
| * receiver in sync with to Metadata/PA. |
| */ |
| public static final int BROADCAST_ASSIST_PA_SYNC_STATE_IN_SYNC = 2; |
| /** |
| * Meta data Sync State |
| * Broadcast receiver sync state w.r.t PA. State INSYNC specifies that broadcast |
| * receiver is failed to sync with Metadata/PA. |
| */ |
| public static final int BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_FAIL = 3; |
| /** |
| * Meta data Sync State |
| * Broadcast receiver sync state w.r.t PA. State SYNC NOPAST denotes that broadcast |
| * receiver needs PAST procedure to sync with Metadata. |
| */ |
| public static final int BROADCAST_ASSIST_PA_SYNC_STATE_NO_PAST = 4; |
| /** |
| * Meta data Sync State |
| * Broadcast receiver sync state w.r.t PA. State SYNC NOPAST denotes that broadcast |
| * receiver needs PAST procedure to sync with Metadata. |
| */ |
| public static final int BROADCAST_ASSIST_PA_SYNC_STATE_INVALID = 0xFFFF; |
| |
| /** @hide */ |
| @IntDef(prefix = "BROADCAST_ASSIST_AUDIO_SYNC_STATE_", value = { |
| BROADCAST_ASSIST_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED, |
| BROADCAST_ASSIST_AUDIO_SYNC_STATE_SYNCHRONIZED |
| }) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface BroadcastAssistAudioSyncState {} |
| |
| /** |
| * Broadcast Audio stream Sync State |
| * Broadcast receiver sync state w.r.t Broadcast Audio stream BIS. denotes |
| * receiver is not synchronized to LE Audio BIS |
| */ |
| public static final int BROADCAST_ASSIST_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED = 0; |
| /** |
| * Broadcast Audio stream Sync State |
| * Broadcast receiver sync state w.r.t Broadcast Audio stream BIS. denotes |
| * receiver is not synchronized to LE Audio BIS |
| */ |
| public static final int BROADCAST_ASSIST_AUDIO_SYNC_STATE_SYNCHRONIZED = 1; |
| /** |
| * Broadcast Audio stream Sync State |
| * Broadcast receiver sync state w.r.t Broadcast Audio stream BIS. denotes |
| * receiver is not synchronized to LE Audio BIS |
| */ |
| public static final int BROADCAST_ASSIST_AUDIO_SYNC_STATE_INVALID = 0xFFFF; |
| |
| |
| /** @hide */ |
| @IntDef(prefix = "BROADCAST_ASSIST_ENC_STATE_", value = { |
| BROADCAST_ASSIST_ENC_STATE_UNENCRYPTED, |
| BROADCAST_ASSIST_ENC_STATE_PIN_NEEDED, |
| BROADCAST_ASSIST_ENC_STATE_DECRYPTING |
| }) |
| @Retention(RetentionPolicy.SOURCE) |
| public @interface BroadcastAssistEncryptionState {} |
| /** |
| * Encryption Status at the LE Audio broadcast receiver side |
| * UNENCRYPTED denoted that broadcast receiver is in sync with an uncrypted |
| * broadcasted audio |
| */ |
| public static final int BROADCAST_ASSIST_ENC_STATE_UNENCRYPTED = 0; |
| /** |
| * Encryption Status at the LE Audio broadcast receiver side |
| * PIN_NEEDED denote that the Broadcast receiver needs broadcast PIN |
| * to sync and listen to Broadcasted Audio |
| */ |
| public static final int BROADCAST_ASSIST_ENC_STATE_PIN_NEEDED = 1; |
| /** |
| * Encryption Status at the LE Audio broadcast receiver side |
| * state DECRYPTING denote that the Broadcast receiver is able to decrypt |
| * and listen to the Broadcasted Audio |
| */ |
| public static final int BROADCAST_ASSIST_ENC_STATE_DECRYPTING = 2; |
| /** |
| * Encryption Status at the LE Audio broadcast receiver side |
| * state BADCODE denote that the Broadcast receiver has got bad code |
| * and not able decrypt |
| * Incorrect code that Scan delegator tried to decrypt can be retrieved from |
| * |
| */ |
| public static final int BROADCAST_ASSIST_ENC_STATE_BADCODE = 3; |
| /** |
| * Encryption Status at the LE Audio broadcast receiver side |
| * state DECRYPTING denote that the Broadcast receiver is able to decrypt |
| * and listen to the Broadcasted Audio |
| */ |
| public static final int BROADCAST_ASSIST_ENC_STATE_INVALID = 0xFFFF; |
| |
| /* |
| * Invalid Broadcast source Information Id |
| */ |
| public static final byte BROADCAST_ASSIST_INVALID_SOURCE_ID = (byte)0x00; |
| /* |
| * Invalid Broadcaster Identifier of the given Broadcast Source |
| */ |
| public static final int BROADCASTER_ID_INVALID = 0xFFFF; |
| /** |
| * Used as an int extra field in {@link BleBroadcastAudioScanAssistManager#ACTION_BROADCAST_RECEIVER_STATE} |
| * intent notifys the Broadcast Source Information to Application layer |
| * |
| * <p> Source Info object can be extracted using this extra field at Application layer |
| * |
| * This is used to read the {@link BleBroadcastSourceInfo } parcelable object |
| * @hide |
| */ |
| public static final String EXTRA_SOURCE_INFO = "android.bluetooth.device.extra.SOURCE_INFO"; |
| /** |
| * Used as an int extra field in {@link BleBroadcastAudioScanAssistManager#ACTION_BROADCAST_RECEIVER_STATE} |
| * intent Broadcast Source Information to Application layer |
| * |
| * <p> Index of the Source Info object can be extracted using this extra field at Application layer |
| * |
| * This is used to read the {@link BleBroadcastSourceInfo } parcelable object |
| * @hide |
| */ |
| public static final String EXTRA_SOURCE_INFO_INDEX = "android.bluetooth.device.extra.SOURCE_INFO_INDEX"; |
| /** |
| * Used as an int extra field in {@link BleBroadcastAudioScanAssistManager#ACTION_BROADCAST_RECEIVER_STATE} |
| * intent notifys the Broadcast Source Information to Application layer |
| * |
| * <p> Maximm number of the Broadcast Source Information that given broadcast receiver can hold, can be extracted using |
| * this extra field at Application layer |
| * |
| * @hide |
| */ |
| public static final String EXTRA_MAX_NUM_SOURCE_INFOS = "android.bluetooth.device.extra.MAX_NUM_SOURCE_INFOS"; |
| private byte mSourceId; |
| private @BroadcastAssistAddressType int mSourceAddressType; |
| private BluetoothDevice mSourceDevice; |
| private byte mSourceAdvSid; |
| private int mBroadcasterId; |
| private @BroadcastAssistMetadataSyncState int mMetaDataSyncState; |
| private @BroadcastAssistAudioSyncState int mAudioSyncState; |
| private Map<Integer, Integer> mAudioBisIndexList = new HashMap <Integer, Integer>(); |
| private @BroadcastAssistEncryptionState int mEncyptionStatus; |
| private Map<Integer, byte[]> mMetadataList = new HashMap<Integer, byte[]>(); |
| private String mBroadcastCode; |
| private byte[] mBadBroadcastCode; |
| private byte mNumSubGroups; |
| private static final int BIS_NO_PREF = 0xFFFFFFFF; |
| private static final int BROADCAST_CODE_SIZE = 16; |
| |
| /** |
| * Constructor to create an Empty object of {@link BleBroadcastSourceInfo } with given source Id, |
| * which contains, Broadcast reciever state information for Broadcast Assistant Usecases. |
| * |
| * This is mainly used to represent the Empty Broadcast source entries |
| * |
| * @param sourceId Source Id for this broadcast source info object |
| * |
| * @deprecated |
| * @hide |
| */ |
| @Deprecated |
| public BleBroadcastSourceInfo (byte sourceId) { |
| mSourceId = sourceId; |
| mMetaDataSyncState = BROADCAST_ASSIST_PA_SYNC_STATE_INVALID; |
| mAudioSyncState = BROADCAST_ASSIST_AUDIO_SYNC_STATE_INVALID; |
| mSourceAddressType = BROADCAST_ASSIST_ADDRESS_TYPE_INVALID; |
| mSourceDevice = null; |
| mSourceAdvSid = (byte)0x00; |
| mEncyptionStatus = BROADCAST_ASSIST_ENC_STATE_INVALID; |
| mBroadcastCode = null; |
| mBadBroadcastCode = null; |
| mNumSubGroups = 0; |
| mBroadcasterId = BROADCASTER_ID_INVALID; |
| } |
| /** |
| * Constructor to create an object of {@link BleBroadcastSourceInfo } which contains |
| * Broadcast reciever state information for Broadcast Assistant Usecases. |
| * This is mainly used for input purpose of {@link BleBroadcastAudioScanAssistManager#addBroadcastSource} |
| * operation |
| * |
| * @param audioSource BluetoothDevice object whcih is selected as Broadcast source |
| * @param advSid advertising Sid of the Broadcast source device for which reciever synchronized with. |
| * @param addressType type of address. This can be be one of {@link #BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC} or |
| * {@link #BROADCAST_ASSIST_ADDRESS_TYPE_RANDOM} |
| * @param metadataSyncState sync status of metadata at the receiver side from this Broadcast source. This can |
| * be one of {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IDLE}, {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNCINFO_REQ}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IN_SYNC}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_FAIL} OR {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_NO_PAST} |
| * @param audioSyncState Audio sync status of metadata at the receiver side from this broadcast source. This can be |
| * one of {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED} OR |
| * {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_SYNCHRONIZED} |
| * @param audioBisIndex Audio BIS index for what Broadcast reciever synchronized with |
| * @param metadataLength Length of the metadata field |
| * @prama metadata metadata information about the type Broadcast information being synchronized at receiver side |
| * |
| * |
| * @hide |
| */ |
| /*package*/ BleBroadcastSourceInfo (BluetoothDevice audioSource, |
| byte advSid, |
| @BroadcastAssistAddressType int addressType, |
| @BroadcastAssistMetadataSyncState int metadataSyncstate, |
| @BroadcastAssistAudioSyncState int audioSyncstate, |
| List<BleBroadcastSourceChannel> selectedBISIndicies |
| ) { |
| mMetaDataSyncState = metadataSyncstate; |
| mAudioSyncState = audioSyncstate; |
| mSourceAddressType = addressType; |
| mSourceDevice = audioSource; |
| mSourceAdvSid = advSid; |
| mBroadcasterId = BROADCASTER_ID_INVALID; |
| if (selectedBISIndicies == null) { |
| BASS_Debug(TAG, "selectedBISIndiciesList is null"); |
| } else { |
| for (int i=0; i<selectedBISIndicies.size(); i++) { |
| if (selectedBISIndicies.get(i).getStatus() == true) { |
| Integer audioBisIndex = 0; |
| int subGroupId = selectedBISIndicies.get(i).getSubGroupId(); |
| if (mAudioBisIndexList.containsKey(subGroupId)) { |
| audioBisIndex = mAudioBisIndexList.get(subGroupId); |
| } |
| audioBisIndex = audioBisIndex | (1<<selectedBISIndicies.get(i).getIndex()); |
| BASS_Debug(TAG, "index" + selectedBISIndicies.get(i).getIndex() + "is set"); |
| mAudioBisIndexList.put(subGroupId, audioBisIndex); |
| } |
| } |
| } |
| |
| //not valid info |
| mSourceId = BROADCAST_ASSIST_INVALID_SOURCE_ID; |
| mEncyptionStatus = BROADCAST_ASSIST_ENC_STATE_INVALID; |
| mBroadcastCode = null; |
| mBadBroadcastCode = null; |
| mNumSubGroups = 0; |
| } |
| |
| /** |
| * Constructor override to create an object of {@link BleBroadcastSourceInfo } which contains |
| * Broadcast reciever state information for Broadcast Assistant Usecases. |
| * |
| * This is mainly used for output purpose to create an object from the receiver state information |
| * read from the remote BASS server. This will be packed and broadcasted as an Intent using |
| * {@link #ACTION_BROADCAST_RECEIVER_STATE} |
| * |
| * @param audioSource BluetoothDevice object whcih is selected as Broadcast source |
| * @param sourceId Source Id for this broadcast source info object |
| * @param advSid advertising Sid of the Broadcast source device for which reciever synchronized with |
| * @param addressType type of address. This can be be one of {@link #BLE_ASSIST_ADDRESS_TYPE_PUBLIC} or |
| * {@link #BLE_ASSIST_ADDRESS_TYPE_RANDOM} |
| * @param metadataSyncState sync status of metadata at the receiver side from this Broadcast source. This can |
| * be one of {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IDLE}, {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNCINFO_REQ}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IN_SYNC}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_FAIL} OR {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_NO_PAST} |
| * @param audioSyncState Audio sync status of metadata at the receiver side from this broadcast source. This can be |
| * one of {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED} OR |
| * {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_SYNCHRONIZED} |
| * @param encryptionStatus Encryotion state at Broadcast receiver. This can be one of {@link #BROADCAST_ASSIST_ENC_STATE_UNENCRYPTED}, |
| {@link #BROADCAST_ASSIST_ENC_STATE_PIN_NEEDED} OR {@link #BROADCAST_ASSIST_ENC_STATE_DECRYPTING} |
| * @param audioBisIndex Audio BIS index for what Broadcast reciever synchronized with |
| * @param metadataLength Length of the metadata field |
| * @prama metadata metadata information about the type Broadcast information being synchronized at receiver side |
| * |
| * |
| * @deprecated |
| * @hide |
| */ |
| @Deprecated |
| public BleBroadcastSourceInfo (BluetoothDevice audioSource, |
| byte sourceId, |
| byte advSid, |
| int broadcasterId, |
| @BroadcastAssistAddressType int addressType, |
| @BroadcastAssistMetadataSyncState int metadataSyncstate, |
| @BroadcastAssistEncryptionState int encryptionStatus, |
| byte[] badCode, |
| byte numSubGroups, |
| @BroadcastAssistAudioSyncState int audioSyncstate, |
| Map<Integer, List<BleBroadcastSourceChannel>> selectedBISIndiciesList, |
| Map<Integer, byte[]> metadataList |
| ) { |
| mSourceId = sourceId; |
| mSourceAddressType = addressType; |
| mSourceDevice = audioSource; |
| mSourceAdvSid = advSid; |
| mBroadcasterId = broadcasterId; |
| mMetaDataSyncState = metadataSyncstate; |
| mAudioSyncState = audioSyncstate; |
| mEncyptionStatus = encryptionStatus; |
| if (badCode != null) { |
| mBadBroadcastCode = new byte[BROADCAST_CODE_SIZE]; |
| System.arraycopy(badCode, 0, mBadBroadcastCode, 0, mBadBroadcastCode.length); |
| } |
| mNumSubGroups = numSubGroups; |
| int audioBisIndex = 0; |
| if (selectedBISIndiciesList != null) { |
| for (Map.Entry<Integer, List<BleBroadcastSourceChannel>> entry : selectedBISIndiciesList.entrySet()) { |
| List<BleBroadcastSourceChannel> selectedBISIndicies = entry.getValue(); |
| if (selectedBISIndicies == null) { |
| //do nothing |
| BASS_Debug(TAG, "selectedBISIndiciesList is null"); |
| } else { |
| for (int i=0; i<selectedBISIndicies.size(); i++) { |
| if (selectedBISIndicies.get(i).getStatus() == true) { |
| audioBisIndex = audioBisIndex | (1<<selectedBISIndicies.get(i).getIndex()); |
| BASS_Debug(TAG, "index" + selectedBISIndicies.get(i).getIndex() + "is set"); |
| } |
| } |
| } |
| BASS_Debug(TAG, "subGroupId:" + entry.getKey() + "audioBisIndex" + audioBisIndex); |
| mAudioBisIndexList.put(entry.getKey(), audioBisIndex); |
| } |
| } |
| if (metadataList != null) { |
| for (Map.Entry<Integer, byte[]> entry : metadataList.entrySet()) { |
| byte[] metadata = entry.getValue(); |
| if (metadata != null && metadata.length != 0) { |
| byte[] mD = new byte[metadata.length]; |
| System.arraycopy(metadata, 0, mD, 0, metadata.length); |
| } |
| mMetadataList.put(entry.getKey(), metadata); |
| } |
| } |
| } |
| |
| /** |
| * Constructor override to create an object of {@link BleBroadcastSourceInfo } which contains |
| * Broadcast reciever state information for Broadcast Assistant Usecases. |
| * |
| * This is mainly used for output purpose to create an object from the receiver state information |
| * read from the remote BASS server. This will be packed and broadcasted as an Intent using |
| * {@link #ACTION_BROADCAST_RECEIVER_STATE} |
| * |
| * @param audioSource BluetoothDevice object whcih is selected as Broadcast source |
| * @param advSid advertising Sid of the Broadcast source device for which reciever synchronized with |
| * @param addressType type of address. This can be be one of {@link #BLE_ASSIST_ADDRESS_TYPE_PUBLIC} or |
| * {@link #BLE_ASSIST_ADDRESS_TYPE_RANDOM} |
| * @param metadataSyncState sync status of metadata at the receiver side from this Broadcast source. This can |
| * be one of {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IDLE}, {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNCINFO_REQ}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IN_SYNC}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_FAIL} OR {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_NO_PAST} |
| * @param audioSyncState Audio sync status of metadata at the receiver side from this broadcast source. This can be |
| * one of {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED} OR |
| * {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_SYNCHRONIZED} |
| * @param encryptionStatus Encryotion state at Broadcast receiver. This can be one of {@link #BROADCAST_ASSIST_ENC_STATE_UNENCRYPTED}, |
| * {@link #BROADCAST_ASSIST_ENC_STATE_PIN_NEEDED} OR {@link #BROADCAST_ASSIST_ENC_STATE_DECRYPTING} |
| * @param audioBisIndex Audio BIS index for what Broadcast reciever synchronized with |
| * @param metadataLength Length of the metadata field |
| * @prama metadata metadata information about the type Broadcast information being synchronized at receiver side |
| * @param broadcastCode Numeric Character String maximum of 16 characters in length, which serves as broadcast PIN code |
| * |
| * @hide |
| */ |
| /*package*/ BleBroadcastSourceInfo (BluetoothDevice device, |
| byte sourceId, |
| byte advSid, |
| @BroadcastAssistAddressType int addressType, |
| @BroadcastAssistMetadataSyncState int metadataSyncstate, |
| @BroadcastAssistAudioSyncState int audioSyncstate, |
| List<BleBroadcastSourceChannel> selectedBISIndicies, |
| @BroadcastAssistEncryptionState int encryptionStatus, |
| String broadcastCode) { |
| mSourceId = sourceId; |
| mMetaDataSyncState = metadataSyncstate; |
| mAudioSyncState = audioSyncstate; |
| mEncyptionStatus = encryptionStatus; |
| mSourceAddressType = addressType; |
| mSourceDevice = device; |
| mSourceAdvSid = advSid; |
| mBroadcasterId = BROADCASTER_ID_INVALID; |
| if (selectedBISIndicies == null) { |
| BASS_Debug(TAG, "selectedBISIndiciesList is null"); |
| } else { |
| for (int i=0; i<selectedBISIndicies.size(); i++) { |
| if (selectedBISIndicies.get(i).getStatus() == true) { |
| Integer audioBisIndex = 0; |
| int subGroupId = selectedBISIndicies.get(i).getSubGroupId(); |
| if (mAudioBisIndexList.containsKey(subGroupId)) { |
| audioBisIndex = mAudioBisIndexList.get(subGroupId); |
| } |
| audioBisIndex = audioBisIndex | (1<<selectedBISIndicies.get(i).getIndex()); |
| BASS_Debug(TAG, "index" + selectedBISIndicies.get(i).getIndex() + "is set"); |
| BASS_Debug(TAG, "audioBisIndex" + audioBisIndex); |
| mAudioBisIndexList.put(subGroupId, audioBisIndex); |
| } |
| } |
| |
| } |
| /*if (metadata != null && metadata.length != 0) { |
| mMetadata = new byte[metadata.length]; |
| System.arraycopy(metadata, 0, mMetadata, 0, metadata.length); |
| }*/ |
| mBroadcastCode = broadcastCode; |
| mBadBroadcastCode = null; |
| mNumSubGroups = 0; |
| } |
| |
| /*package*/ BleBroadcastSourceInfo (BluetoothDevice device, |
| byte sourceId, |
| byte advSid, |
| int broadcasterId, |
| @BroadcastAssistAddressType int addressType, |
| @BroadcastAssistMetadataSyncState int metadataSyncstate, |
| @BroadcastAssistAudioSyncState int audioSyncstate, |
| @BroadcastAssistEncryptionState int encryptionStatus, |
| String broadcastCode, |
| byte[] badCode, |
| byte numSubGroups, |
| Map<Integer, Integer> bisIndiciesList, |
| Map<Integer, byte[]> metadataList |
| ) { |
| mSourceId = sourceId; |
| mMetaDataSyncState = metadataSyncstate; |
| mAudioSyncState = audioSyncstate; |
| mEncyptionStatus = encryptionStatus; |
| mSourceAddressType = addressType; |
| mSourceDevice = device; |
| mSourceAdvSid = advSid; |
| mBroadcasterId = broadcasterId; |
| mBroadcastCode = broadcastCode; |
| if (badCode != null && badCode.length != 0) { |
| mBadBroadcastCode= new byte[badCode.length]; |
| System.arraycopy(badCode, 0, mBadBroadcastCode, 0, badCode.length); |
| } |
| mNumSubGroups = numSubGroups; |
| mAudioBisIndexList = new HashMap<Integer, Integer> (bisIndiciesList); |
| mMetadataList = new HashMap<Integer, byte[]> (metadataList); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (o instanceof BleBroadcastSourceInfo) { |
| BleBroadcastSourceInfo other = (BleBroadcastSourceInfo) o; |
| BASS_Debug(TAG, "other>> " + o.toString()); |
| BASS_Debug(TAG, "local>> " + toString()); |
| return (other.mSourceId == mSourceId |
| && other.mMetaDataSyncState == mMetaDataSyncState |
| && other.mAudioSyncState == mAudioSyncState |
| && other.mSourceAddressType == mSourceAddressType |
| && other.mSourceDevice == mSourceDevice |
| && other.mSourceAdvSid == mSourceAdvSid |
| && other.mEncyptionStatus == mEncyptionStatus |
| && other.mBroadcastCode == mBroadcastCode |
| && other.mBroadcasterId == mBroadcasterId |
| ); |
| } |
| return false; |
| } |
| |
| public boolean isEmptyEntry() { |
| boolean ret = false; |
| if (mMetaDataSyncState == (int)BROADCAST_ASSIST_PA_SYNC_STATE_INVALID && |
| mAudioSyncState == (int)BROADCAST_ASSIST_AUDIO_SYNC_STATE_INVALID && |
| mSourceAddressType == (int)BROADCAST_ASSIST_ADDRESS_TYPE_INVALID && |
| mSourceDevice == null && |
| mSourceAdvSid == (byte)0 && |
| mEncyptionStatus == (int)BROADCAST_ASSIST_ENC_STATE_INVALID |
| ) { |
| ret = true; |
| } |
| BASS_Debug(TAG, "isEmptyEntry returns: " + ret); |
| return ret; |
| } |
| |
| public boolean matches(BleBroadcastSourceInfo srcInfo) { |
| boolean ret = false; |
| if (srcInfo == null) { |
| ret = false; |
| } else { |
| if (mSourceDevice == null) { |
| if (mSourceAdvSid == srcInfo.getAdvertisingSid() && |
| mSourceAddressType == srcInfo.getAdvAddressType()) { |
| ret = true; |
| } |
| } else { |
| if (mSourceDevice.equals(srcInfo.getSourceDevice()) && |
| mSourceAdvSid == srcInfo.getAdvertisingSid() && |
| mSourceAddressType == srcInfo.getAdvAddressType() && |
| mBroadcasterId == srcInfo.getBroadcasterId()) { |
| ret = true; |
| } |
| } |
| } |
| BASS_Debug(TAG, "matches returns: " + ret); |
| return ret; |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(mSourceId, mMetaDataSyncState, mAudioSyncState, |
| mSourceAddressType, mSourceDevice, mSourceAdvSid, |
| mEncyptionStatus, mBroadcastCode); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| @Override |
| public String toString() { |
| return "{BleBroadcastSourceInfo : mSourceId" + mSourceId |
| + " sourceDevice: " + mSourceDevice |
| + " addressType: " + mSourceAddressType |
| + " mSourceAdvSid:" + mSourceAdvSid |
| + " mMetaDataSyncState:" + mMetaDataSyncState |
| + " mAudioSyncState" + mAudioSyncState |
| + " mEncyptionStatus" + mEncyptionStatus |
| + " mBadBroadcastCode" + mBadBroadcastCode |
| + " mNumSubGroups" + mNumSubGroups |
| + " mBroadcastCode" + mBroadcastCode |
| + " mAudioBisIndexList" + mAudioBisIndexList |
| + " mMetadataList" + mMetadataList |
| + " mBroadcasterId" + mBroadcasterId |
| + "}"; |
| } |
| |
| /** |
| * Gets the Source Id of the BleBroadcastSourceInfo Object |
| * |
| * @return byte representing the Source Id of the Broadcast Source Info Object |
| * {@link #BROADCAST_ASSIST_INVALID_SOURCE_ID} in case if this field is not valid |
| * @hide |
| */ |
| public byte getSourceId () { |
| return mSourceId; |
| } |
| |
| /** |
| * Sets the Source Id of the BleBroadcastSourceInfo Object |
| * |
| * @param byte source Id for the BleBroadcastSourceInfo Object |
| * |
| * @hide |
| */ |
| public void setSourceId (byte sourceId) { |
| mSourceId = sourceId; |
| } |
| |
| /** |
| * Sets the Broadcast source device for the BleBroadcastSourceInfo Object |
| * |
| * @param BluetoothDevice which need to be set as Broadcast source device |
| * @hide |
| */ |
| public void setSourceDevice(BluetoothDevice sourceDevice) { |
| mSourceDevice = sourceDevice; |
| } |
| |
| /** |
| * Gets the Broadcast source Device object from the BleBroadcastSourceInfo Object |
| * |
| * @return BluetoothDevice object for Broadcast source device |
| * @hide |
| */ |
| public BluetoothDevice getSourceDevice () { |
| return mSourceDevice; |
| } |
| |
| /** |
| * Sets the address type of the Broadcast source advertisement for the BleBroadcastSourceInfo Object |
| * |
| * @param byte addressType, this can be one of {@link #BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC} OR {@link #BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC} |
| * @hide |
| */ |
| public void setAdvAddressType(int addressType) { |
| mSourceAddressType = addressType; |
| } |
| |
| /** |
| * Gets the address type of the Broadcast source advertisement for the BleBroadcastSourceInfo Object |
| * |
| * @return byte addressType, this can be one of {@link #BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC} OR {@link #BROADCAST_ASSIST_ADDRESS_TYPE_PUBLIC} |
| * @hide |
| * |
| * @deprecated |
| */ |
| @UnsupportedAppUsage |
| @Deprecated |
| public int getAdvAddressType () { |
| return mSourceAddressType; |
| } |
| |
| /** |
| * Sets the advertising Sid of the Broadcast source advertisement for the BleBroadcastSourceInfo Object |
| * |
| * @param byte advertising Sid value |
| * @hide |
| */ |
| public void setAdvertisingSid(byte advSid) { |
| mSourceAdvSid = advSid; |
| } |
| |
| /** |
| * Gets the advertising Sid of the Broadcast source advertisement for the BleBroadcastSourceInfo Object |
| * |
| * @return byte advertising Sid value |
| * @hide |
| */ |
| public byte getAdvertisingSid () { |
| return mSourceAdvSid; |
| } |
| |
| /** |
| * Gets the Broadcast Id of the Broadcast source of the BleBroadcastSourceInfo Object |
| * |
| * @return int broadcast source Identifier |
| * @hide |
| */ |
| public int getBroadcasterId () { |
| return mBroadcasterId; |
| } |
| |
| /** |
| * Sets the Metadata sync status at the Broadcast receiver side for the BleBroadcastSourceInfo Object |
| * |
| * @param BroadcastAssistMetadataSyncState representing the state of Meta data sync status. this can be one of |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IDLE}, {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNCINFO_REQ}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IN_SYNC}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_FAIL} OR {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_NO_PAST} |
| * |
| * @hide |
| */ |
| /*package*/ void setMetadataSyncState(@BroadcastAssistMetadataSyncState int metadataSyncState) { |
| mMetaDataSyncState = metadataSyncState; |
| } |
| |
| /** |
| * Gets the Metadata sync status at the Broadcast receiver side from the BleBroadcastSourceInfo Object |
| * |
| * @return BroadcastAssistMetadataSyncState representing the state of Meta data sync status. this can be one of |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IDLE}, {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNCINFO_REQ}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_IN_SYNC}, |
| * {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_FAIL} OR {@link #BROADCAST_ASSIST_PA_SYNC_STATE_SYNC_NO_PAST} |
| * |
| * @hide |
| */ |
| public @BroadcastAssistMetadataSyncState int getMetadataSyncState () { |
| return mMetaDataSyncState; |
| } |
| |
| /** |
| * Sets the Audio sync status at the Broadcast receiver side for the BleBroadcastSourceInfo Object |
| * |
| * @param BroadcastAssistAudioSyncState representing the state of Meta data sync status. this can be one of |
| * {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED} OR |
| * {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_SYNCHRONIZED} |
| * |
| * @hide |
| */ |
| /*package*/ void setAudioSyncState(@BroadcastAssistAudioSyncState int audioSyncState) { |
| mAudioSyncState = audioSyncState; |
| } |
| |
| /** |
| * Gets the Audio sync status at the Broadcast receiver side from the BleBroadcastSourceInfo Object |
| * |
| * @return BroadcastAssistAudioSyncState representing the state of Meta data sync status. this can be one of |
| * {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_NOT_SYNCHRONIZED} OR |
| * {@link #BROADCAST_ASSIST_AUDIO_SYNC_STATE_SYNCHRONIZED} * |
| * @hide |
| */ |
| public @BroadcastAssistAudioSyncState int getAudioSyncState () { |
| return mAudioSyncState; |
| } |
| |
| /** |
| * Sets the Encryption status at the Broadcast receiver side for the BleBroadcastSourceInfo Object |
| * |
| * @param BroadcastAssistEncryptionState representing the state of Meta data sync status. This can be one of |
| * {@link #BROADCAST_ASSIST_ENC_STATE_UNENCRYPTED}, |
| * {@link #BROADCAST_ASSIST_ENC_STATE_PIN_NEEDED}, {@link #BROADCAST_ASSIST_ENC_STATE_DECRYPTING} |
| * Or {@link #BROADCAST_ASSIST_ENC_STATE_BADCODE} |
| * @hide |
| */ |
| /*package*/ void setEncryptionStatus(@BroadcastAssistEncryptionState int encryptionStatus) { |
| mEncyptionStatus = encryptionStatus; |
| } |
| |
| /** |
| * Gets the Audio sync status at the Broadcast receiver side from the BleBroadcastSourceInfo Object |
| * |
| * @return BroadcastAssistEncryptionState representing the state of Meta data sync status. This can be one of |
| * {@link #BROADCAST_ASSIST_ENC_STATE_UNENCRYPTED}, |
| * {@link #BROADCAST_ASSIST_ENC_STATE_PIN_NEEDED} ,{@link #BROADCAST_ASSIST_ENC_STATE_DECRYPTING} |
| * Or {@link #BROADCAST_ASSIST_ENC_STATE_BADCODE} |
| * @hide |
| */ |
| public @BroadcastAssistEncryptionState int getEncryptionStatus () { |
| return mEncyptionStatus; |
| } |
| |
| /** |
| * Gets the Incorrect Broadcast code with which Scan delegator try |
| * decrypt the Broadcast audio and failed |
| * |
| * This code is valid only if {@link #getEncryptionStatus} returns |
| * {@link #BROADCAST_ASSIST_ENC_STATE_BADCODE} |
| * |
| * @param byte[] byte array containing bad broadcast value |
| * null if the current Encryptetion status is |
| * not {@link #BROADCAST_ASSIST_ENC_STATE_BADCODE} |
| * |
| * @hide |
| */ |
| public byte[] getBadBroadcastCode () { |
| return mBadBroadcastCode; |
| } |
| |
| /** |
| * Gets the number of subgroups of the BleBroadcastSourceInfo Object |
| * |
| * @return byte number of subgroups |
| * @hide |
| * |
| * @deprecated |
| */ |
| @UnsupportedAppUsage |
| @Deprecated |
| public byte getNumberOfSubGroups () { |
| return mNumSubGroups; |
| } |
| |
| /** |
| * Sets the Audio Broadcast channels to which receiver need to be synchronized with, |
| * for BleBroadcastSourceInfo Object |
| * |
| * |
| * @param int audioBis Index to which reciever need to be synchronized with |
| * @hide |
| */ |
| /*package*/ void setBroadcastChannelsSyncStatus(List<BleBroadcastSourceChannel> selectedBISIndicies) { |
| if (selectedBISIndicies == null) { |
| //set No preference |
| BASS_Debug(TAG, "selectedBISIndiciesList is null"); |
| return; |
| } |
| for (int i=0; i<selectedBISIndicies.size(); i++) { |
| if (selectedBISIndicies.get(i).getStatus() == true) { |
| Integer audioBisIndex = 0; |
| int subGroupId = selectedBISIndicies.get(i).getSubGroupId(); |
| if (mAudioBisIndexList.containsKey(subGroupId)) { |
| audioBisIndex = mAudioBisIndexList.get(subGroupId); |
| } |
| audioBisIndex = audioBisIndex | (1<<selectedBISIndicies.get(i).getIndex()); |
| BASS_Debug(TAG, "index" + selectedBISIndicies.get(i).getIndex() + "is set"); |
| mAudioBisIndexList.put(subGroupId, audioBisIndex); |
| } |
| } |
| |
| } |
| /** |
| * Gets the Broadcast channels index and the sync status from BleBroadcastSourceInfo Object |
| * This maps the various broadcast source indicies and sync status of them |
| * |
| * @param int audio BIS index from the BleBroadcastSourceInfo object |
| * @hide |
| */ |
| public List<BleBroadcastSourceChannel> getBroadcastChannelsSyncStatus () { |
| List<BleBroadcastSourceChannel> bcastIndicies = new ArrayList<BleBroadcastSourceChannel>(); |
| for (int i=0; i<mNumSubGroups; i++) { |
| int bisIndexValue = mAudioBisIndexList.get(i); |
| int index =0; |
| while (bisIndexValue != 0) { |
| if ((bisIndexValue&0x01) == 0x01) { |
| BleBroadcastSourceChannel bI = |
| new BleBroadcastSourceChannel(index, String.valueOf(index), true, i, mMetadataList.get(i)); |
| bcastIndicies.add(bI); |
| } |
| bisIndexValue = bisIndexValue>>1; |
| index++; |
| } |
| } |
| |
| BASS_Debug(TAG, "returning Bisindicies:" + bcastIndicies); |
| return bcastIndicies; |
| } |
| |
| @UnsupportedAppUsage |
| @Deprecated |
| public Map<Integer, Integer> getBisIndexList() { |
| return mAudioBisIndexList; |
| } |
| |
| /*package*/ void setBroadcastCode(String broadcastCode) { |
| mBroadcastCode = broadcastCode; |
| } |
| |
| @UnsupportedAppUsage |
| @Deprecated |
| public void setBroadcasterId(int broadcasterId) { |
| mBroadcasterId = broadcasterId; |
| } |
| |
| /** |
| * Gets the broadcastCode value from BleBroadcastSourceInfo Object |
| * |
| * @param String broadcast code from the BleBroadcastSourceInfo object |
| * @hide |
| * |
| * @deprecated |
| */ |
| @UnsupportedAppUsage |
| @Deprecated |
| public String getBroadcastCode () { |
| return mBroadcastCode; |
| } |
| |
| private void writeMapToParcel(Parcel dest, Map<Integer, Integer> bisIndexList) { |
| dest.writeInt(bisIndexList.size()); |
| for (Map.Entry<Integer, Integer> entry : bisIndexList.entrySet()) { |
| dest.writeInt(entry.getKey()); |
| dest.writeInt(entry.getValue()); |
| } |
| } |
| |
| private static void readMapFromParcel(Parcel in, Map<Integer, Integer> bisIndexList) { |
| int size = in.readInt(); |
| |
| for (int i = 0; i < size; i++) { |
| Integer key = in.readInt(); |
| Integer value = in.readInt(); |
| bisIndexList.put(key, value); |
| } |
| } |
| |
| private void writeMetadataListToParcel(Parcel dest, Map<Integer, byte[]> metadataList) { |
| dest.writeInt(metadataList.size()); |
| for (Map.Entry<Integer, byte[]> entry : metadataList.entrySet()) { |
| dest.writeInt(entry.getKey()); |
| byte[] metadata = entry.getValue(); |
| if (metadata != null) { |
| dest.writeInt(metadata.length); |
| dest.writeByteArray(metadata); |
| } |
| } |
| } |
| |
| private static void readMetadataListFromParcel(Parcel in, Map<Integer, byte[]> metadataList) { |
| int size = in.readInt(); |
| |
| for (int i = 0; i < size; i++) { |
| Integer key = in.readInt(); |
| Integer metaDataLen = in.readInt(); |
| byte[] metadata = null; |
| if (metaDataLen != 0) { |
| metadata = new byte[metaDataLen]; |
| in.readByteArray(metadata); |
| } |
| metadataList.put(key, metadata); |
| } |
| } |
| |
| public static final @android.annotation.NonNull Parcelable.Creator<BleBroadcastSourceInfo> CREATOR = |
| new Parcelable.Creator<BleBroadcastSourceInfo>() { |
| public BleBroadcastSourceInfo createFromParcel(Parcel in) { |
| |
| BASS_Debug(TAG, "createFromParcel>"); |
| final byte sourceId = in.readByte(); |
| final int sourceAddressType = in.readInt(); |
| final BluetoothDevice sourceDevice = in.readTypedObject( |
| BluetoothDevice.CREATOR); |
| final byte sourceAdvSid = in.readByte(); |
| final int broadcastId = in.readInt(); |
| BASS_Debug(TAG, "broadcastId" + broadcastId); |
| final int metaDataSyncState = in.readInt(); |
| final int audioSyncState = in.readInt(); |
| BASS_Debug(TAG, "audioSyncState" + audioSyncState); |
| final int encyptionStatus = in.readInt(); |
| final int badBroadcastLen = in.readInt(); |
| byte[] badBroadcastCode = null; |
| if (badBroadcastLen > 0) { |
| badBroadcastCode = new byte[badBroadcastLen]; |
| in.readByteArray(badBroadcastCode); |
| } |
| final byte numSubGroups = in.readByte(); |
| final String broadcastCode = in.readString(); |
| Map<Integer,Integer> bisIndexList = new HashMap <Integer, Integer>(); |
| readMapFromParcel(in, bisIndexList); |
| Map<Integer,byte[]> metadataList = new HashMap <Integer, byte[]>(); |
| readMetadataListFromParcel(in, metadataList); |
| |
| BleBroadcastSourceInfo srcInfo = new BleBroadcastSourceInfo(sourceDevice, sourceId, sourceAdvSid, broadcastId, |
| sourceAddressType, metaDataSyncState,audioSyncState, |
| encyptionStatus, broadcastCode, badBroadcastCode, numSubGroups, bisIndexList, metadataList); |
| BASS_Debug(TAG, "createFromParcel:" + srcInfo); |
| return srcInfo; |
| } |
| |
| public BleBroadcastSourceInfo[] newArray(int size) { |
| return new BleBroadcastSourceInfo[size]; |
| } |
| }; |
| |
| @Override |
| public void writeToParcel(Parcel out, int flags) { |
| BASS_Debug(TAG, "writeToParcel>"); |
| out.writeByte(mSourceId); |
| out.writeInt(mSourceAddressType); |
| out.writeTypedObject(mSourceDevice, 0); |
| out.writeByte(mSourceAdvSid); |
| out.writeInt(mBroadcasterId); |
| out.writeInt(mMetaDataSyncState); |
| out.writeInt(mAudioSyncState); |
| out.writeInt(mEncyptionStatus); |
| if (mBadBroadcastCode != null) { |
| out.writeInt(mBadBroadcastCode.length); |
| out.writeByteArray(mBadBroadcastCode); |
| } else { |
| //write ZERO to parcel to say no badBroadcastcode |
| out.writeInt(0); |
| } |
| out.writeByte(mNumSubGroups); |
| out.writeString(mBroadcastCode); |
| writeMapToParcel(out, mAudioBisIndexList); |
| writeMetadataListToParcel(out, mMetadataList); |
| BASS_Debug(TAG, "writeToParcel:" + toString()); |
| } |
| |
| static void BASS_Debug(String TAG, String msg) { |
| if (BASS_DBG) { |
| Log.d(TAG, msg); |
| } |
| } |
| |
| }; |
| |