/******************************************************************************
 *
 *  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);
        }
    }

};

