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

Commit 18965897 authored by SongFerngWang's avatar SongFerngWang
Browse files

[BT LE broadcast sink] Initialize the sourceId

If the sink device has connected the broadcast source, then the device
should initialize the sourceId and create the sourceId's preference UI.

Bug: 231576575
Test: manually test
Change-Id: I24d9e6d4c78dc4e583c5253e552456a68b1114c3
parent c389149f
Loading
Loading
Loading
Loading
+49 −7
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package com.android.settings.bluetooth;

import android.bluetooth.BluetoothLeAudioContentMetadata;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothLeBroadcastSubgroup;
import android.content.Context;
import android.graphics.drawable.Drawable;
@@ -43,16 +45,15 @@ class BluetoothBroadcastSourcePreference extends Preference {
    private static final int RESOURCE_ID_ICON = R.drawable.settings_input_antenna;

    private BluetoothLeBroadcastMetadata mBluetoothLeBroadcastMetadata;
    private BluetoothLeBroadcastReceiveState mBluetoothLeBroadcastReceiveState;
    private ImageView mFrictionImageView;
    private String mTitle;
    private boolean mStatus;
    private boolean mIsEncrypted;

    BluetoothBroadcastSourcePreference(@NonNull Context context,
            @NonNull BluetoothLeBroadcastMetadata source) {
    BluetoothBroadcastSourcePreference(@NonNull Context context) {
        super(context);
        initUi();
        updateMetadataAndRefreshUi(source, false);
    }

    @Override
@@ -68,7 +69,7 @@ class BluetoothBroadcastSourcePreference extends Preference {
    private void initUi() {
        setLayoutResource(R.layout.preference_access_point);
        setWidgetLayoutResource(R.layout.access_point_friction_widget);

        mTitle = getContext().getString(RESOURCE_ID_UNKNOWN_PROGRAM_INFO);
        mStatus = false;
        final Drawable drawable = getContext().getDrawable(RESOURCE_ID_ICON);
        if (drawable != null) {
@@ -105,9 +106,20 @@ class BluetoothBroadcastSourcePreference extends Preference {
     */
    public void updateMetadataAndRefreshUi(BluetoothLeBroadcastMetadata source, boolean status) {
        mBluetoothLeBroadcastMetadata = source;
        mTitle = getBroadcastMetadataProgramInfo();
        mTitle = getProgramInfo();
        mIsEncrypted = mBluetoothLeBroadcastMetadata.isEncrypted();
        mStatus = status;
        mStatus = status || mBluetoothLeBroadcastReceiveState != null;

        refresh();
    }

    /**
     * Updates the title and status from BluetoothLeBroadcastReceiveState.
     */
    public void updateReceiveStateAndRefreshUi(BluetoothLeBroadcastReceiveState receiveState) {
        mBluetoothLeBroadcastReceiveState = receiveState;
        mTitle = getProgramInfo();
        mStatus = true;

        refresh();
    }
@@ -124,7 +136,17 @@ class BluetoothBroadcastSourcePreference extends Preference {
        updateStatusButton();
    }

    private String getBroadcastMetadataProgramInfo() {
    private String getProgramInfo() {
        if (mBluetoothLeBroadcastReceiveState != null) {
            List<BluetoothLeAudioContentMetadata> bluetoothLeAudioContentMetadata =
                    mBluetoothLeBroadcastReceiveState.getSubgroupMetadata();
            if (!bluetoothLeAudioContentMetadata.isEmpty()) {
                return bluetoothLeAudioContentMetadata.stream()
                        .map(i -> i.getProgramInfo())
                        .findFirst().orElse(
                                getContext().getString(RESOURCE_ID_UNKNOWN_PROGRAM_INFO));
            }
        }
        if (mBluetoothLeBroadcastMetadata == null) {
            return getContext().getString(RESOURCE_ID_UNKNOWN_PROGRAM_INFO);
        }
@@ -138,4 +160,24 @@ class BluetoothBroadcastSourcePreference extends Preference {
                .filter(i -> !TextUtils.isEmpty(i))
                .findFirst().orElse(getContext().getString(RESOURCE_ID_UNKNOWN_PROGRAM_INFO));
    }

    /**
     * Whether the broadcast source is encrypted or not.
     * @return If true, the broadcast source needs the broadcast code. If false, the broadcast
     * source does not need the broadcast code.
     */
    public boolean isEncrypted() {
        return mIsEncrypted;
    }

    /**
     * Clear the BluetoothLeBroadcastReceiveState and reset the state when the user clicks the
     * "leave broadcast" button.
     */
    public void clearReceiveState() {
        mBluetoothLeBroadcastReceiveState = null;
        mTitle = getProgramInfo();
        mStatus = false;
        refresh();
    }
}
+67 −12
Original line number Diff line number Diff line
@@ -86,9 +86,7 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
                @Override
                public void onSearchStarted(int reason) {
                    Log.d(TAG, "onSearchStarted: " + reason);

                    getActivity().runOnUiThread(
                            () -> cacheRemoveAllPrefs(mBroadcastSourceListCategory));
                    getActivity().runOnUiThread(() -> handleSearchStarted());
                }

                @Override
@@ -109,7 +107,8 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
                @Override
                public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {
                    Log.d(TAG, "onSourceFound:");
                    getActivity().runOnUiThread(() -> updateListCategory(source, false));
                    getActivity().runOnUiThread(
                            () -> updateListCategoryFromBroadcastMetadata(source, false));
                }

                @Override
@@ -119,7 +118,7 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
                        Log.w(TAG, "onSourceAdded: mSelectedPreference == null!");
                        return;
                    }
                    getActivity().runOnUiThread(() -> updateListCategory(
                    getActivity().runOnUiThread(() -> updateListCategoryFromBroadcastMetadata(
                            mSelectedPreference.getBluetoothLeBroadcastMetadata(), true));
                }

@@ -144,6 +143,7 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
                public void onSourceRemoved(@NonNull BluetoothDevice sink, int sourceId,
                        int reason) {
                    Log.d(TAG, "onSourceRemoved:");
                    getActivity().runOnUiThread(() -> handleSourceRemoved());
                }

                @Override
@@ -215,6 +215,8 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
        //check assistant status. Start searching...
        if (mLeBroadcastAssistant != null && !mLeBroadcastAssistant.isSearchInProgress()) {
            mLeBroadcastAssistant.startSearchingForSources(getScanFilter());
        } else {
            addConnectedSourcePreference();
        }
    }

@@ -310,11 +312,13 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
        return Collections.emptyList();
    }

    private void updateListCategory(BluetoothLeBroadcastMetadata source, boolean isConnected) {
    private void updateListCategoryFromBroadcastMetadata(BluetoothLeBroadcastMetadata source,
            boolean isConnected) {
        BluetoothBroadcastSourcePreference item = mBroadcastSourceListCategory.findPreference(
                Integer.toString(source.getBroadcastId()));
        if (item == null) {
            item = createBluetoothBroadcastSourcePreference(source);
            item = createBluetoothBroadcastSourcePreference();
            item.setKey(Integer.toString(source.getBroadcastId()));
            mBroadcastSourceListCategory.addPreference(item);
        }
        item.updateMetadataAndRefreshUi(source, isConnected);
@@ -326,13 +330,36 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
        }
    }

    private BluetoothBroadcastSourcePreference createBluetoothBroadcastSourcePreference(
            BluetoothLeBroadcastMetadata source) {
    private void updateListCategoryFromBroadcastReceiveState(
            BluetoothLeBroadcastReceiveState receiveState) {
        BluetoothBroadcastSourcePreference item = mBroadcastSourceListCategory.findPreference(
                Integer.toString(receiveState.getBroadcastId()));
        if (item == null) {
            item = createBluetoothBroadcastSourcePreference();
            item.setKey(Integer.toString(receiveState.getBroadcastId()));
            mBroadcastSourceListCategory.addPreference(item);
        }
        item.updateReceiveStateAndRefreshUi(receiveState);
        item.setOrder(0);

        setSourceId(receiveState.getSourceId());
        mSelectedPreference = item;

        //refresh the header
        if (mBluetoothFindBroadcastsHeaderController != null) {
            mBluetoothFindBroadcastsHeaderController.refreshUi();
        }
    }

    private BluetoothBroadcastSourcePreference createBluetoothBroadcastSourcePreference() {
        BluetoothBroadcastSourcePreference pref = new BluetoothBroadcastSourcePreference(
                getContext(), source);
        pref.setKey(Integer.toString(source.getBroadcastId()));
                getContext());
        pref.setOnPreferenceClickListener(preference -> {
            if (source.isEncrypted()) {
            if (pref.getBluetoothLeBroadcastMetadata() == null) {
                Log.d(TAG, "BluetoothLeBroadcastMetadata is null, do nothing.");
                return false;
            }
            if (pref.isEncrypted()) {
                launchBroadcastCodeDialog(pref);
            } else {
                addSource(pref);
@@ -383,6 +410,10 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
                .setPositiveButton(R.string.bluetooth_connect_access_dialog_positive,
                        (d, w) -> {
                            Log.d(TAG, "setPositiveButton: clicked");
                            if (pref.getBluetoothLeBroadcastMetadata() == null) {
                                Log.d(TAG, "BluetoothLeBroadcastMetadata is null, do nothing.");
                                return;
                            }
                            addBroadcastCodeIntoPreference(pref, editText.getText().toString());
                            addSource(pref);
                        })
@@ -392,6 +423,30 @@ public class BluetoothFindBroadcastsFragment extends RestrictedDashboardFragment
        alertDialog.show();
    }

    private void handleSearchStarted() {
        cacheRemoveAllPrefs(mBroadcastSourceListCategory);
        addConnectedSourcePreference();
    }

    private void handleSourceRemoved() {
        if (mSelectedPreference != null) {
            if (mSelectedPreference.getBluetoothLeBroadcastMetadata() == null) {
                mBroadcastSourceListCategory.removePreference(mSelectedPreference);
            } else {
                mSelectedPreference.clearReceiveState();
            }
        }
        mSelectedPreference = null;
    }

    private void addConnectedSourcePreference() {
        List<BluetoothLeBroadcastReceiveState> receiveStateList =
                mLeBroadcastAssistant.getAllSources(mCachedDevice.getDevice());
        if (!receiveStateList.isEmpty()) {
            updateListCategoryFromBroadcastReceiveState(receiveStateList.get(0));
        }
    }

    public int getSourceId() {
        return mSourceId;
    }