Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a837beb1 authored by Betty Chang's avatar Betty Chang Committed by Automerger Merge Worker
Browse files

Merge "[LE Audio] To fix the QR Code parse error" am: 114052e5

parents 5eb562f5 114052e5
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -53,8 +53,8 @@ public final class BluetoothBroadcastUtils {
    static final String PREFIX_BT_SYNC_INTERVAL = "SI:";
    static final String PREFIX_BT_SYNC_INTERVAL = "SI:";
    static final String PREFIX_BT_IS_ENCRYPTED = "E:";
    static final String PREFIX_BT_IS_ENCRYPTED = "E:";
    static final String PREFIX_BT_BROADCAST_CODE = "C:";
    static final String PREFIX_BT_BROADCAST_CODE = "C:";
    static final String PREFIX_BT_PRESENTATION_DELAY = "D:";
    static final String PREFIX_BT_PRESENTATION_DELAY = "PD:";
    static final String PREFIX_BT_SUBGROUPS = "G:";
    static final String PREFIX_BT_SUBGROUPS = "SG:";
    static final String PREFIX_BT_ANDROID_VERSION = "V:";
    static final String PREFIX_BT_ANDROID_VERSION = "V:";


    // BluetoothLeBroadcastSubgroup
    // BluetoothLeBroadcastSubgroup
+136 −62
Original line number Original line Diff line number Diff line
@@ -28,7 +28,9 @@ import android.util.Log;
import java.nio.charset.StandardCharsets;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.Pattern;


@@ -38,6 +40,43 @@ public class LocalBluetoothLeBroadcastMetadata {
    private static final String METADATA_START = "<";
    private static final String METADATA_START = "<";
    private static final String METADATA_END = ">";
    private static final String METADATA_END = ">";
    private static final String PATTERN_REGEX = "<(.*?)>";
    private static final String PATTERN_REGEX = "<(.*?)>";
    private static final String PATTERN_BT_BROADCAST_METADATA =
            "T:<(.*?)>;+D:<(.*?)>;+AS:<(.*?)>;+B:<(.*?)>;+SI:<(.*?)>;+E:<(.*?)>;+C:<(.*?)>;"
                + "+PD:<(.*?)>;+SG:(.*)";
    private static final String PATTERN_BT_SUBGROUP =
            "CID:<(.*?)>;+CC:<(.*?);>;+AC:<(.*?);>;+CP:<(.*?)>;+BC:<(.*)>;>;";
    private static final String PATTERN_BT_CHANNEL = "CI:<(.*?)>;+BCCM:<(.*?);>;";

    /* Index for BluetoothLeBroadcastMetadata */
    private static int MATCH_INDEX_ADDRESS_TYPE = 1;
    private static int MATCH_INDEX_DEVICE = 2;
    private static int MATCH_INDEX_ADVERTISING_SID = 3;
    private static int MATCH_INDEX_BROADCAST_ID = 4;
    private static int MATCH_INDEX_SYNC_INTERVAL = 5;
    private static int MATCH_INDEX_IS_ENCRYPTED = 6;
    private static int MATCH_INDEX_BROADCAST_CODE = 7;
    private static int MATCH_INDEX_PRESENTATION_DELAY = 8;
    private static int MATCH_INDEX_SUBGROUPS = 9;

    /* Index for BluetoothLeBroadcastSubgroup */
    private static int MATCH_INDEX_CODEC_ID = 1;
    private static int MATCH_INDEX_CODEC_CONFIG = 2;
    private static int MATCH_INDEX_AUDIO_CONTENT = 3;
    private static int MATCH_INDEX_CHANNEL_PREF = 4;
    private static int MATCH_INDEX_BROADCAST_CHANNEL = 5;

    /* Index for BluetoothLeAudioCodecConfigMetadata */
    private static int LIST_INDEX_AUDIO_LOCATION = 0;
    private static int LIST_INDEX_CODEC_CONFIG_RAW_METADATA = 1;

    /* Index for BluetoothLeAudioContentMetadata */
    private static int LIST_INDEX_PROGRAM_INFO = 0;
    private static int LIST_INDEX_LANGUAGE = 1;
    private static int LIST_INDEX_AUDIO_CONTENT_RAW_METADATA = 2;

    /* Index for BluetoothLeBroadcastChannel */
    private static int MATCH_INDEX_CHANNEL_INDEX = 1;
    private static int MATCH_INDEX_CHANNEL_CODEC_CONFIG = 2;


    private BluetoothLeBroadcastSubgroup mSubgroup;
    private BluetoothLeBroadcastSubgroup mSubgroup;
    private List<BluetoothLeBroadcastSubgroup> mSubgroupList;
    private List<BluetoothLeBroadcastSubgroup> mSubgroupList;
@@ -55,17 +94,20 @@ public class LocalBluetoothLeBroadcastMetadata {
    private byte[] mBroadcastCode;
    private byte[] mBroadcastCode;


    // BluetoothLeBroadcastSubgroup
    // BluetoothLeBroadcastSubgroup
    private long mCodecId;
    private int mCodecId;
    private BluetoothLeAudioContentMetadata mContentMetadata;
    private BluetoothLeAudioContentMetadata mContentMetadata;
    private BluetoothLeAudioCodecConfigMetadata mConfigMetadata;
    private BluetoothLeAudioCodecConfigMetadata mConfigMetadata;
    private BluetoothLeBroadcastChannel mChannel;
    private Boolean mNoChannelPreference;
    private List<BluetoothLeBroadcastChannel> mChannel;


    // BluetoothLeAudioCodecConfigMetadata
    // BluetoothLeAudioCodecConfigMetadata
    private long mAudioLocation;
    private long mAudioLocation;
    private byte[] mCodecConfigMetadata;


    // BluetoothLeAudioContentMetadata
    // BluetoothLeAudioContentMetadata
    private String mLanguage;
    private String mLanguage;
    private String mProgramInfo;
    private String mProgramInfo;
    private byte[] mAudioContentMetadata;


    // BluetoothLeBroadcastChannel
    // BluetoothLeBroadcastChannel
    private boolean mIsSelected;
    private boolean mIsSelected;
@@ -135,6 +177,7 @@ public class LocalBluetoothLeBroadcastMetadata {
        for (BluetoothLeBroadcastSubgroup subgroup: subgroupList) {
        for (BluetoothLeBroadcastSubgroup subgroup: subgroupList) {
            String audioCodec = convertAudioCodecConfigToString(subgroup.getCodecSpecificConfig());
            String audioCodec = convertAudioCodecConfigToString(subgroup.getCodecSpecificConfig());
            String audioContent = convertAudioContentToString(subgroup.getContentMetadata());
            String audioContent = convertAudioContentToString(subgroup.getContentMetadata());
            boolean hasChannelPreference = subgroup.hasChannelPreference();
            String channels = convertChannelToString(subgroup.getChannels());
            String channels = convertChannelToString(subgroup.getChannels());
            subgroupString = new StringBuilder()
            subgroupString = new StringBuilder()
                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_ID)
                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_ID)
@@ -146,6 +189,9 @@ public class LocalBluetoothLeBroadcastMetadata {
                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_AUDIO_CONTENT)
                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_AUDIO_CONTENT)
                    .append(METADATA_START).append(audioContent).append(METADATA_END)
                    .append(METADATA_START).append(audioContent).append(METADATA_END)
                    .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
                    .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_CHANNEL_PREF)
                    .append(METADATA_START).append(hasChannelPreference).append(METADATA_END)
                    .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_BROADCAST_CHANNEL)
                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_BROADCAST_CHANNEL)
                    .append(METADATA_START).append(channels).append(METADATA_END)
                    .append(METADATA_START).append(channels).append(METADATA_END)
                    .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
                    .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
@@ -211,26 +257,35 @@ public class LocalBluetoothLeBroadcastMetadata {
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "Convert " + qrCodeString + "to BluetoothLeBroadcastMetadata");
            Log.d(TAG, "Convert " + qrCodeString + "to BluetoothLeBroadcastMetadata");
        }
        }
        Pattern pattern = Pattern.compile(PATTERN_REGEX);

        Pattern pattern = Pattern.compile(PATTERN_BT_BROADCAST_METADATA);
        Matcher match = pattern.matcher(qrCodeString);
        Matcher match = pattern.matcher(qrCodeString);
        if (match.find()) {
        if (match.find()) {
            ArrayList<String> resultList = new ArrayList<>();
            mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
            resultList.add(match.group(1));
            mSourceAddressType = Integer.parseInt(resultList.get(0));
            mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
            mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
                    resultList.get(1));
                    match.group(MATCH_INDEX_DEVICE));
            mSourceAdvertisingSid = Integer.parseInt(resultList.get(2));
            mSourceAdvertisingSid = Integer.parseInt(match.group(MATCH_INDEX_ADVERTISING_SID));
            mBroadcastId = Integer.parseInt(resultList.get(3));
            mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
            mPaSyncInterval = Integer.parseInt(resultList.get(4));
            mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
            mIsEncrypted = Boolean.valueOf(resultList.get(5));
            mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
            mBroadcastCode = resultList.get(6).getBytes();
            mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
            mPresentationDelayMicros = Integer.parseInt(resultList.get(7));
            mPresentationDelayMicros =
            mSubgroup = convertToSubgroup(resultList.get(8));
                  Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));


            if (DEBUG) {
            if (DEBUG) {
                Log.d(TAG, "Converted qrCodeString result: " + match.group());
                Log.d(TAG, "Converted qrCodeString result: "
                        + " ,Type = " + mSourceAddressType
                        + " ,Device = " + mSourceDevice
                        + " ,AdSid = " + mSourceAdvertisingSid
                        + " ,BroadcastId = " + mBroadcastId
                        + " ,paSync = " + mPaSyncInterval
                        + " ,encrypted = " + mIsEncrypted
                        + " ,BroadcastCode = " + Arrays.toString(mBroadcastCode)
                        + " ,delay = " + mPresentationDelayMicros);
            }
            }


            mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));

            return new BluetoothLeBroadcastMetadata.Builder()
            return new BluetoothLeBroadcastMetadata.Builder()
                    .setSourceDevice(mSourceDevice, mSourceAddressType)
                    .setSourceDevice(mSourceDevice, mSourceAddressType)
                    .setSourceAdvertisingSid(mSourceAdvertisingSid)
                    .setSourceAdvertisingSid(mSourceAdvertisingSid)
@@ -254,26 +309,26 @@ public class LocalBluetoothLeBroadcastMetadata {
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "Convert " + subgroupString + "to BluetoothLeBroadcastSubgroup");
            Log.d(TAG, "Convert " + subgroupString + "to BluetoothLeBroadcastSubgroup");
        }
        }
        Pattern pattern = Pattern.compile(PATTERN_REGEX);
        Pattern pattern = Pattern.compile(PATTERN_BT_SUBGROUP);
        Matcher match = pattern.matcher(subgroupString);
        Matcher match = pattern.matcher(subgroupString);
        if (match.find()) {
        if (match.find()) {
            ArrayList<String> resultList = new ArrayList<>();
            mCodecId = Integer.parseInt(match.group(MATCH_INDEX_CODEC_ID));
            resultList.add(match.group(1));
            mConfigMetadata = convertToConfigMetadata(match.group(MATCH_INDEX_CODEC_CONFIG));
            mCodecId = Long.getLong(resultList.get(0));
            mContentMetadata = convertToContentMetadata(match.group(MATCH_INDEX_AUDIO_CONTENT));
            mConfigMetadata = convertToConfigMetadata(resultList.get(1));
            mNoChannelPreference = Boolean.valueOf(match.group(MATCH_INDEX_CHANNEL_PREF));
            mContentMetadata = convertToContentMetadata(resultList.get(2));
            mChannel =
            mChannel = convertToChannel(resultList.get(3), mConfigMetadata);
                  convertToChannel(match.group(MATCH_INDEX_BROADCAST_CHANNEL), mConfigMetadata);


            if (DEBUG) {
            BluetoothLeBroadcastSubgroup.Builder subgroupBuilder =
                Log.d(TAG, "Converted subgroupString result: " + match.group());
                    new BluetoothLeBroadcastSubgroup.Builder();
            }
            subgroupBuilder.setCodecId(mCodecId);

            subgroupBuilder.setCodecSpecificConfig(mConfigMetadata);
            return new BluetoothLeBroadcastSubgroup.Builder()
            subgroupBuilder.setContentMetadata(mContentMetadata);
                    .setCodecId(mCodecId)

                    .setCodecSpecificConfig(mConfigMetadata)
            for (BluetoothLeBroadcastChannel channel : mChannel) {
                    .setContentMetadata(mContentMetadata)
                subgroupBuilder.addChannel(channel);
                    .addChannel(mChannel)
            }
                    .build();
            return subgroupBuilder.build();
        } else {
        } else {
            if (DEBUG) {
            if (DEBUG) {
                Log.d(TAG,
                Log.d(TAG,
@@ -291,15 +346,17 @@ public class LocalBluetoothLeBroadcastMetadata {
        }
        }
        Pattern pattern = Pattern.compile(PATTERN_REGEX);
        Pattern pattern = Pattern.compile(PATTERN_REGEX);
        Matcher match = pattern.matcher(configMetadataString);
        Matcher match = pattern.matcher(configMetadataString);
        if (match.find()) {
        ArrayList<String> resultList = new ArrayList<>();
        ArrayList<String> resultList = new ArrayList<>();
        while (match.find()) {
            resultList.add(match.group(1));
            resultList.add(match.group(1));
            mAudioLocation = Long.getLong(resultList.get(0));
            Log.d(TAG, "Codec Config match : " + match.group(1));

        }
        if (DEBUG) {
        if (DEBUG) {
                Log.d(TAG, "Converted configMetadataString result: " + match.group());
            Log.d(TAG, "Converted configMetadataString result: " + resultList.size());
        }
        }

        if (resultList.size() > 0) {
            mAudioLocation = Long.parseLong(resultList.get(LIST_INDEX_AUDIO_LOCATION));
            mCodecConfigMetadata = resultList.get(LIST_INDEX_CODEC_CONFIG_RAW_METADATA).getBytes();
            return new BluetoothLeAudioCodecConfigMetadata.Builder()
            return new BluetoothLeAudioCodecConfigMetadata.Builder()
                    .setAudioLocation(mAudioLocation)
                    .setAudioLocation(mAudioLocation)
                    .build();
                    .build();
@@ -319,14 +376,25 @@ public class LocalBluetoothLeBroadcastMetadata {
        }
        }
        Pattern pattern = Pattern.compile(PATTERN_REGEX);
        Pattern pattern = Pattern.compile(PATTERN_REGEX);
        Matcher match = pattern.matcher(contentMetadataString);
        Matcher match = pattern.matcher(contentMetadataString);
        if (match.find()) {
        ArrayList<String> resultList = new ArrayList<>();
        ArrayList<String> resultList = new ArrayList<>();
        while (match.find()) {
            Log.d(TAG, "Audio Content match : " + match.group(1));
            resultList.add(match.group(1));
            resultList.add(match.group(1));
            mProgramInfo = resultList.get(0);
        }
            mLanguage = resultList.get(1);

        if (DEBUG) {
        if (DEBUG) {
                Log.d(TAG, "Converted contentMetadataString result: " + match.group());
            Log.d(TAG, "Converted contentMetadataString result: " + resultList.size());
        }
        if (resultList.size() > 0) {
            mProgramInfo = resultList.get(LIST_INDEX_PROGRAM_INFO);
            mLanguage = resultList.get(LIST_INDEX_LANGUAGE);
            mAudioContentMetadata =
                  resultList.get(LIST_INDEX_AUDIO_CONTENT_RAW_METADATA).getBytes();

            /* TODO(b/265253566) : Need to set the default value for language when the user starts
            *  the broadcast.
            */
            if (mLanguage.equals("null")) {
                mLanguage = "eng";
            }
            }


            return new BluetoothLeAudioContentMetadata.Builder()
            return new BluetoothLeAudioContentMetadata.Builder()
@@ -342,28 +410,34 @@ public class LocalBluetoothLeBroadcastMetadata {
        }
        }
    }
    }


    private BluetoothLeBroadcastChannel convertToChannel(String channelString,
    private List<BluetoothLeBroadcastChannel> convertToChannel(String channelString,
            BluetoothLeAudioCodecConfigMetadata configMetadata) {
            BluetoothLeAudioCodecConfigMetadata configMetadata) {
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, "Convert " + channelString + "to BluetoothLeBroadcastChannel");
            Log.d(TAG, "Convert " + channelString + "to BluetoothLeBroadcastChannel");
        }
        }
        Pattern pattern = Pattern.compile(PATTERN_REGEX);
        Pattern pattern = Pattern.compile(PATTERN_BT_CHANNEL);
        Matcher match = pattern.matcher(channelString);
        Matcher match = pattern.matcher(channelString);
        if (match.find()) {
        Map<Integer, BluetoothLeAudioCodecConfigMetadata> channel =
            ArrayList<String> resultList = new ArrayList<>();
                new HashMap<Integer, BluetoothLeAudioCodecConfigMetadata>();
            resultList.add(match.group(1));
        while (match.find()) {
            mIsSelected = Boolean.valueOf(resultList.get(0));
            channel.put(Integer.parseInt(match.group(MATCH_INDEX_CHANNEL_INDEX)),
            mChannelIndex = Integer.parseInt(resultList.get(1));
                    convertToConfigMetadata(match.group(MATCH_INDEX_CHANNEL_CODEC_CONFIG)));

            if (DEBUG) {
                Log.d(TAG, "Converted channelString result: " + match.group());
        }
        }


            return new BluetoothLeBroadcastChannel.Builder()
        if (channel.size() > 0) {
            mIsSelected = false;
            ArrayList<BluetoothLeBroadcastChannel> broadcastChannelList = new ArrayList<>();
            for (Map.Entry<Integer, BluetoothLeAudioCodecConfigMetadata> entry :
                    channel.entrySet()) {

                broadcastChannelList.add(
                        new BluetoothLeBroadcastChannel.Builder()
                            .setSelected(mIsSelected)
                            .setSelected(mIsSelected)
                    .setChannelIndex(mChannelIndex)
                            .setChannelIndex(entry.getKey())
                    .setCodecMetadata(configMetadata)
                            .setCodecMetadata(entry.getValue())
                    .build();
                            .build());
            }
            return broadcastChannelList;
        } else {
        } else {
            if (DEBUG) {
            if (DEBUG) {
                Log.d(TAG,
                Log.d(TAG,