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

Commit 63037367 authored by Yiyi Shen's avatar Yiyi Shen
Browse files

[Audiosharing] Move time consuming work to background.

Bug: 305620450
Test: manual
Change-Id: I9192d8ebbcd12d0bf13d0145d8a2e47cb8da5edd
parent bf6e273c
Loading
Loading
Loading
Loading
+163 −116
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ import com.android.settingslib.bluetooth.LeAudioProfile;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.utils.ThreadUtils;

import com.google.common.collect.ImmutableList;

import java.util.ArrayList;
import java.util.List;
@@ -260,6 +263,9 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
            return;
        }
        mLocalBtManager.getEventManager().registerCallback(this);
        if (DEBUG) {
            Log.d(TAG, "onStart() Register callbacks for broadcast and assistant.");
        }
        mBroadcast.registerServiceCallBack(mExecutor, mBroadcastCallback);
        mAssistant.registerServiceCallBack(mExecutor, mBroadcastAssistantCallback);
        mBluetoothDeviceUpdater.registerCallback();
@@ -281,15 +287,11 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
            return;
        }
        mLocalBtManager.getEventManager().unregisterCallback(this);
        // TODO: verify the reason for failing to unregister
        try {
        if (DEBUG) {
            Log.d(TAG, "onStop() Unregister callbacks for broadcast and assistant.");
        }
        mBroadcast.unregisterServiceCallBack(mBroadcastCallback);
        mAssistant.unregisterServiceCallBack(mBroadcastAssistantCallback);
        } catch (IllegalArgumentException e) {
            Log.e(
                    TAG,
                    "Fail to unregister broadcast or assistant callback due to " + e.getMessage());
        }
        mBluetoothDeviceUpdater.unregisterCallback();
    }

@@ -358,6 +360,28 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
                    "Ignore onProfileConnectionStateChanged, no broadcast or assistant supported");
            return;
        }
        var unused =
                ThreadUtils.postOnBackgroundThread(
                        () -> handleOnProfileStateChanged(cachedDevice, bluetoothProfile));
    }

    /**
     * Initialize the controller.
     *
     * @param fragment The fragment to provide the context and metrics category for {@link
     *     AudioSharingBluetoothDeviceUpdater} and provide the host for dialogs.
     */
    public void init(DashboardFragment fragment) {
        mFragment = fragment;
        mBluetoothDeviceUpdater =
                new AudioSharingBluetoothDeviceUpdater(
                        fragment.getContext(),
                        AudioSharingDevicePreferenceController.this,
                        fragment.getMetricsCategory());
    }

    private void handleOnProfileStateChanged(
            @NonNull CachedBluetoothDevice cachedDevice, int bluetoothProfile) {
        boolean isLeAudioSupported = isLeAudioSupported(cachedDevice);
        // For eligible (LE audio) remote device, we only check its connected LE audio profile.
        if (isLeAudioSupported && bluetoothProfile != BluetoothProfile.LE_AUDIO) {
@@ -384,14 +408,26 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
        }
        if (!isLeAudioSupported) {
            // Handle connected ineligible (non LE audio) remote device
            handleOnProfileStateChangedForNonLeAudioDevice(cachedDevice);
        } else {
            // Handle connected eligible (LE audio) remote device
            handleOnProfileStateChangedForLeAudioDevice(cachedDevice);
        }
    }

    private void handleOnProfileStateChangedForNonLeAudioDevice(
            @NonNull CachedBluetoothDevice cachedDevice) {
        if (isBroadcasting()) {
            // Show stop audio sharing dialog when an ineligible (non LE audio) remote device
            // connected during a sharing session.
            ThreadUtils.postOnMainThread(
                    () -> {
                        closeOpeningDialogs();
                        AudioSharingStopDialogFragment.show(
                                mFragment,
                                cachedDevice.getName(),
                                () -> mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId()));
                    });
        } else {
            // Do nothing for ineligible (non LE audio) remote device when no sharing session.
            if (DEBUG) {
@@ -401,11 +437,26 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
                                + " sharing session");
            }
        }
        } else {
    }

    private void handleOnProfileStateChangedForLeAudioDevice(
            @NonNull CachedBluetoothDevice cachedDevice) {
        Map<Integer, List<CachedBluetoothDevice>> groupedDevices =
                AudioSharingUtils.fetchConnectedDevicesByGroupId(mLocalBtManager);
            // Handle connected eligible (LE audio) remote device
        if (isBroadcasting()) {
            if (groupedDevices.containsKey(cachedDevice.getGroupId())
                    && groupedDevices.get(cachedDevice.getGroupId()).stream()
                            .anyMatch(
                                    device ->
                                            AudioSharingUtils.hasBroadcastSource(
                                                    device, mLocalBtManager))) {
                Log.d(
                        TAG,
                        "Automatically add another device within the same group to the sharing: "
                                + cachedDevice.getDevice().getAnonymizedAddress());
                addSourceToTargetDevices(ImmutableList.of(cachedDevice.getDevice()));
                return;
            }
            // Show audio sharing switch or join dialog according to device count in the sharing
            // session.
            ArrayList<AudioSharingDeviceItem> deviceItemsInSharingSession =
@@ -414,6 +465,8 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
            // Show audio sharing switch dialog when the third eligible (LE audio) remote device
            // connected during a sharing session.
            if (deviceItemsInSharingSession.size() >= 2) {
                ThreadUtils.postOnMainThread(
                        () -> {
                            closeOpeningDialogs();
                            AudioSharingDisconnectDialogFragment.show(
                                    mFragment,
@@ -421,12 +474,16 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
                                    cachedDevice.getName(),
                                    (AudioSharingDeviceItem item) -> {
                                        // Remove all sources from the device user clicked
                                        if (groupedDevices.containsKey(item.getGroupId())) {
                                            for (CachedBluetoothDevice device :
                                                    groupedDevices.get(item.getGroupId())) {
                                                for (BluetoothLeBroadcastReceiveState source :
                                            mAssistant.getAllSources(device.getDevice())) {
                                                        mAssistant.getAllSources(
                                                                device.getDevice())) {
                                                    mAssistant.removeSource(
                                                device.getDevice(), source.getSourceId());
                                                            device.getDevice(),
                                                            source.getSourceId());
                                                }
                                            }
                                        }
                                        // Add current broadcast to the latest connected device
@@ -435,9 +492,12 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
                                                mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
                                                /* isGroupOp= */ true);
                                    });
                        });
            } else {
                // Show audio sharing join dialog when the first or second eligible (LE audio)
                // remote device connected during a sharing session.
                ThreadUtils.postOnMainThread(
                        () -> {
                            closeOpeningDialogs();
                            AudioSharingJoinDialogFragment.show(
                                    mFragment,
@@ -450,21 +510,23 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
                                                mBroadcast.getLatestBluetoothLeBroadcastMetadata(),
                                                /* isGroupOp= */ true);
                                    });
                        });
            }
        } else {
            ArrayList<AudioSharingDeviceItem> deviceItems = new ArrayList<>();
            for (List<CachedBluetoothDevice> devices : groupedDevices.values()) {
                    // Use random device in the group within the sharing session to
                    // represent the group.
                // Use random device in the group within the sharing session to represent the group.
                CachedBluetoothDevice device = devices.get(0);
                if (device.getGroupId() == cachedDevice.getGroupId()) {
                    continue;
                }
                deviceItems.add(AudioSharingUtils.buildAudioSharingDeviceItem(device));
            }
                // Show audio sharing join dialog when the second eligible (LE audio) remote device
                // connect and no sharing session.
            // Show audio sharing join dialog when the second eligible (LE audio) remote
            // device connect and no sharing session.
            if (deviceItems.size() == 1) {
                ThreadUtils.postOnMainThread(
                        () -> {
                            closeOpeningDialogs();
                            AudioSharingJoinDialogFragment.show(
                                    mFragment,
@@ -480,25 +542,10 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro
                                        }
                                        mBroadcast.startBroadcast("test", null);
                                    });
                        });
            }
        }
    }
    }

    /**
     * Initialize the controller.
     *
     * @param fragment The fragment to provide the context and metrics category for {@link
     *     AudioSharingBluetoothDeviceUpdater} and provide the host for dialogs.
     */
    public void init(DashboardFragment fragment) {
        mFragment = fragment;
        mBluetoothDeviceUpdater =
                new AudioSharingBluetoothDeviceUpdater(
                        fragment.getContext(),
                        AudioSharingDevicePreferenceController.this,
                        fragment.getMetricsCategory());
    }

    private boolean isLeAudioSupported(CachedBluetoothDevice cachedDevice) {
        return cachedDevice.getProfiles().stream()