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

Commit 4e7b979d authored by Łukasz Rymanowski's avatar Łukasz Rymanowski Committed by Automerger Merge Worker
Browse files

Merge "LeAudio: Fix for IllegalStateException" into main am: 53c7d848

parents 24f9a421 53c7d848
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.le_audio.LeAudioService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.nio.charset.StandardCharsets;
@@ -3260,7 +3261,8 @@ public class BassClientService extends ProfileService {
        private static final int MSG_RECEIVESTATE_CHANGED = 12;
        private static final int MSG_SOURCE_LOST = 13;

        private final RemoteCallbackList<IBluetoothLeBroadcastAssistantCallback> mCallbacks =
        @GuardedBy("mCallbacksList")
        private final RemoteCallbackList<IBluetoothLeBroadcastAssistantCallback> mCallbacksList =
                new RemoteCallbackList<>();

        Callbacks(Looper looper) {
@@ -3268,11 +3270,15 @@ public class BassClientService extends ProfileService {
        }

        public void register(IBluetoothLeBroadcastAssistantCallback callback) {
            mCallbacks.register(callback);
            synchronized (mCallbacksList) {
                mCallbacksList.register(callback);
            }
        }

        public void unregister(IBluetoothLeBroadcastAssistantCallback callback) {
            mCallbacks.unregister(callback);
            synchronized (mCallbacksList) {
                mCallbacksList.unregister(callback);
            }
        }

        private void checkForPendingGroupOpRequest(Message msg) {
@@ -3309,17 +3315,20 @@ public class BassClientService extends ProfileService {
        @Override
        public void handleMessage(Message msg) {
            checkForPendingGroupOpRequest(msg);
            final int n = mCallbacks.beginBroadcast();

            synchronized (mCallbacksList) {
                final int n = mCallbacksList.beginBroadcast();
                for (int i = 0; i < n; i++) {
                    final IBluetoothLeBroadcastAssistantCallback callback =
                        mCallbacks.getBroadcastItem(i);
                            mCallbacksList.getBroadcastItem(i);
                    try {
                        invokeCallback(callback, msg);
                    } catch (RemoteException e) {
                        continue;
                    }
                }
            mCallbacks.finishBroadcast();
                mCallbacksList.finishBroadcast();
            }
        }

        private static class ObjParams {
+20 −15
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import com.android.bluetooth.btservice.ServiceFactory;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.flags.Flags;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
@@ -80,7 +81,9 @@ public class HapClientService extends ProfileService {
    private final Map<BluetoothDevice, Integer> mDeviceFeaturesMap = new HashMap<>();
    private final Map<BluetoothDevice, List<BluetoothHapPresetInfo>> mPresetsMap = new HashMap<>();

    @VisibleForTesting RemoteCallbackList<IBluetoothHapClientCallback> mCallbacks;
    @VisibleForTesting
    @GuardedBy("mCallbacks")
    final RemoteCallbackList<IBluetoothHapClientCallback> mCallbacks = new RemoteCallbackList<>();

    @VisibleForTesting ServiceFactory mFactory = new ServiceFactory();

@@ -153,8 +156,6 @@ public class HapClientService extends ProfileService {
        mStateMachinesThread = new HandlerThread("HapClientService.StateMachines");
        mStateMachinesThread.start();

        mCallbacks = new RemoteCallbackList<IBluetoothHapClientCallback>();

        // Initialize native interface
        mHapClientNativeInterface.init();

@@ -576,7 +577,7 @@ public class HapClientService extends ProfileService {
     */
    public void selectPreset(BluetoothDevice device, int presetIndex) {
        if (presetIndex == BluetoothHapClient.PRESET_INDEX_UNAVAILABLE) {
            if (mCallbacks != null) {
            synchronized (mCallbacks) {
                int n = mCallbacks.beginBroadcast();
                for (int i = 0; i < n; i++) {
                    try {
@@ -613,7 +614,7 @@ public class HapClientService extends ProfileService {
        }

        if (status != BluetoothStatusCodes.SUCCESS) {
            if (mCallbacks != null) {
            synchronized (mCallbacks) {
                int n = mCallbacks.beginBroadcast();
                for (int i = 0; i < n; i++) {
                    try {
@@ -744,7 +745,7 @@ public class HapClientService extends ProfileService {
        List current_presets = mPresetsMap.get(device);
        if (current_presets == null) return;

        if (mCallbacks != null) {
        synchronized (mCallbacks) {
            int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -775,7 +776,7 @@ public class HapClientService extends ProfileService {

    private void notifyActivePresetChanged(
            BluetoothDevice device, int presetIndex, int reasonCode) {
        if (mCallbacks != null) {
        synchronized (mCallbacks) {
            int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -819,7 +820,7 @@ public class HapClientService extends ProfileService {
    }

    private void notifySelectActivePresetFailed(BluetoothDevice device, int statusCode) {
        if (mCallbacks != null) {
        synchronized (mCallbacks) {
            int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -836,7 +837,7 @@ public class HapClientService extends ProfileService {
    }

    private void notifySelectActivePresetForGroupFailed(int groupId, int statusCode) {
        if (mCallbacks != null) {
        synchronized (mCallbacks) {
            int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -853,7 +854,7 @@ public class HapClientService extends ProfileService {
    }

    private void notifySetPresetNameFailed(BluetoothDevice device, int statusCode) {
        if (mCallbacks != null) {
        synchronized (mCallbacks) {
            int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -870,7 +871,7 @@ public class HapClientService extends ProfileService {
    }

    private void notifySetPresetNameForGroupFailed(int groupId, int statusCode) {
        if (mCallbacks != null) {
        synchronized (mCallbacks) {
            int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -930,7 +931,7 @@ public class HapClientService extends ProfileService {
     */
    public void setPresetName(BluetoothDevice device, int presetIndex, String name) {
        if (!isPresetIndexValid(device, presetIndex)) {
            if (mCallbacks != null) {
            synchronized (mCallbacks) {
                int n = mCallbacks.beginBroadcast();
                for (int i = 0; i < n; i++) {
                    try {
@@ -969,7 +970,7 @@ public class HapClientService extends ProfileService {
            status = BluetoothStatusCodes.ERROR_HAP_INVALID_PRESET_INDEX;
        }
        if (status != BluetoothStatusCodes.SUCCESS) {
            if (mCallbacks != null) {
            synchronized (mCallbacks) {
                int n = mCallbacks.beginBroadcast();
                for (int i = 0; i < n; i++) {
                    try {
@@ -1557,8 +1558,10 @@ public class HapClientService extends ProfileService {
            }

            enforceBluetoothPrivilegedPermission(service);
            synchronized (service.mCallbacks) {
                service.mCallbacks.register(callback);
            }
        }

        @Override
        public void unregisterCallback(
@@ -1572,7 +1575,9 @@ public class HapClientService extends ProfileService {
            }

            enforceBluetoothPrivilegedPermission(service);
            synchronized (service.mCallbacks) {
                service.mCallbacks.unregister(callback);
            }
        }
    }
}
+34 −24
Original line number Diff line number Diff line
@@ -208,9 +208,15 @@ public class LeAudioService extends ProfileService {

    @VisibleForTesting BassClientService mBassClientService;

    @VisibleForTesting RemoteCallbackList<IBluetoothLeBroadcastCallback> mBroadcastCallbacks;
    @VisibleForTesting
    @GuardedBy("mBroadcastCallbacks")
    final RemoteCallbackList<IBluetoothLeBroadcastCallback> mBroadcastCallbacks =
            new RemoteCallbackList<>();

    @VisibleForTesting RemoteCallbackList<IBluetoothLeAudioCallback> mLeAudioCallbacks;
    @VisibleForTesting
    @GuardedBy("mLeAudioCallbacks")
    final RemoteCallbackList<IBluetoothLeAudioCallback> mLeAudioCallbacks =
            new RemoteCallbackList<>();

    BluetoothLeScanner mAudioServersScanner;
    /* When mScanCallback is not null, it means scan is started. */
@@ -443,9 +449,6 @@ public class LeAudioService extends ProfileService {
            mGroupWriteLock.unlock();
        }

        // Setup broadcast callbacks
        mLeAudioCallbacks = new RemoteCallbackList<IBluetoothLeAudioCallback>();

        mTmapRoleMask =
                LeAudioTmapGattServer.TMAP_ROLE_FLAG_CG | LeAudioTmapGattServer.TMAP_ROLE_FLAG_UMS;

@@ -454,7 +457,6 @@ public class LeAudioService extends ProfileService {
                        & (1 << BluetoothProfile.LE_AUDIO_BROADCAST))
                != 0) {
            Log.i(TAG, "Init Le Audio broadcaster");
            mBroadcastCallbacks = new RemoteCallbackList<IBluetoothLeBroadcastCallback>();
            mLeAudioBroadcasterNativeInterface =
                    Objects.requireNonNull(
                            LeAudioBroadcasterNativeInterface.getInstance(),
@@ -2644,7 +2646,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyGroupStreamStatusChanged(int groupId, int groupStreamStatus) {
        if (mLeAudioCallbacks != null) {
        synchronized (mLeAudioCallbacks) {
            int n = mLeAudioCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4422,7 +4424,7 @@ public class LeAudioService extends ProfileService {
            volumeControlService.handleGroupNodeAdded(groupId, device);
        }

        if (mLeAudioCallbacks != null) {
        synchronized (mLeAudioCallbacks) {
            int n = mLeAudioCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4504,7 +4506,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyGroupNodeRemoved(BluetoothDevice device, int groupId) {
        if (mLeAudioCallbacks != null) {
        synchronized (mLeAudioCallbacks) {
            int n = mLeAudioCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4518,7 +4520,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyGroupStatusChanged(int groupId, int status) {
        if (mLeAudioCallbacks != null) {
        synchronized (mLeAudioCallbacks) {
            int n = mLeAudioCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4546,7 +4548,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyBroadcastStarted(Integer broadcastId, int reason) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4560,7 +4562,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyBroadcastStartFailed(int reason) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4574,7 +4576,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyOnBroadcastStopped(Integer broadcastId, int reason) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4588,7 +4590,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyOnBroadcastStopFailed(int reason) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4602,7 +4604,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyPlaybackStarted(Integer broadcastId, int reason) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4616,7 +4618,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyPlaybackStopped(Integer broadcastId, int reason) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4630,7 +4632,7 @@ public class LeAudioService extends ProfileService {
    }

    private void notifyBroadcastUpdateFailed(int broadcastId, int reason) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -4647,7 +4649,7 @@ public class LeAudioService extends ProfileService {

    private void notifyBroadcastMetadataChanged(
            int broadcastId, BluetoothLeBroadcastMetadata metadata) {
        if (mBroadcastCallbacks != null) {
        synchronized (mBroadcastCallbacks) {
            int n = mBroadcastCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -5219,12 +5221,14 @@ public class LeAudioService extends ProfileService {
            Objects.requireNonNull(source, "source cannot be null");

            LeAudioService service = getService(source);
            if ((service == null) || (service.mLeAudioCallbacks == null)) {
            if (service == null) {
                return;
            }

            enforceBluetoothPrivilegedPermission(service);
            synchronized (service.mLeAudioCallbacks) {
                service.mLeAudioCallbacks.register(callback);
            }
            if (!service.mBluetoothEnabled) {
                service.handleBluetoothEnabled();
            }
@@ -5237,13 +5241,15 @@ public class LeAudioService extends ProfileService {
            Objects.requireNonNull(source, "source cannot be null");

            LeAudioService service = getService(source);
            if ((service == null) || (service.mLeAudioCallbacks == null)) {
            if (service == null) {
                return;
            }

            enforceBluetoothPrivilegedPermission(service);
            synchronized (service.mLeAudioCallbacks) {
                service.mLeAudioCallbacks.unregister(callback);
            }
        }

        @Override
        public void registerLeBroadcastCallback(
@@ -5257,8 +5263,10 @@ public class LeAudioService extends ProfileService {
            }

            enforceBluetoothPrivilegedPermission(service);
            synchronized (service.mBroadcastCallbacks) {
                service.mBroadcastCallbacks.register(callback);
            }
        }

        @Override
        public void unregisterLeBroadcastCallback(
@@ -5272,8 +5280,10 @@ public class LeAudioService extends ProfileService {
            }

            enforceBluetoothPrivilegedPermission(service);
            synchronized (service.mBroadcastCallbacks) {
                service.mBroadcastCallbacks.unregister(callback);
            }
        }

        @Override
        public void startBroadcast(
+50 −43
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.csip.CsipSetCoordinatorService;
import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.le_audio.LeAudioService;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import libcore.util.SneakyThrow;
@@ -85,7 +86,10 @@ public class VolumeControlService extends ProfileService {
    private HandlerThread mStateMachinesThread;
    private Handler mHandler = null;

    @VisibleForTesting RemoteCallbackList<IBluetoothVolumeControlCallback> mCallbacks;
    @VisibleForTesting
    @GuardedBy("mCallbacks")
    final RemoteCallbackList<IBluetoothVolumeControlCallback> mCallbacks =
            new RemoteCallbackList<>();

    @VisibleForTesting
    static class VolumeControlOffsetDescriptor {
@@ -251,7 +255,6 @@ public class VolumeControlService extends ProfileService {
        mGroupVolumeCache.clear();
        mGroupMuteCache.clear();
        mDeviceVolumeCache.clear();
        mCallbacks = new RemoteCallbackList<IBluetoothVolumeControlCallback>();

        // Mark service as started
        setVolumeControlService(this);
@@ -312,7 +315,6 @@ public class VolumeControlService extends ProfileService {

        if (mCallbacks != null) {
            mCallbacks.kill();
            mCallbacks = null;
        }
    }

@@ -766,12 +768,23 @@ public class VolumeControlService extends ProfileService {

    void registerCallback(IBluetoothVolumeControlCallback callback) {
        Log.d(TAG, "registerCallback: " + callback);

        synchronized (mCallbacks) {
            /* Here we keep all the user callbacks */
            mCallbacks.register(callback);
        }

        notifyNewCallbackOfKnownVolumeInfo(callback);
    }

    void unregisterCallback(IBluetoothVolumeControlCallback callback) {
        Log.d(TAG, "unregisterCallback: " + callback);

        synchronized (mCallbacks) {
            mCallbacks.unregister(callback);
        }
    }

    void notifyNewRegisteredCallback(IBluetoothVolumeControlCallback callback) {
        Log.d(TAG, "notifyNewRegisteredCallback: " + callback);
        notifyNewCallbackOfKnownVolumeInfo(callback);
@@ -1048,10 +1061,7 @@ public class VolumeControlService extends ProfileService {
        }
        offsets.setValue(id, value);

        if (mCallbacks == null) {
            return;
        }

        synchronized (mCallbacks) {
            int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                try {
@@ -1062,6 +1072,7 @@ public class VolumeControlService extends ProfileService {
            }
            mCallbacks.finishBroadcast();
        }
    }

    void handleDeviceExtAudioLocationChanged(BluetoothDevice device, int id, int location) {
        Log.d(TAG, " device: " + device + " offset_id: " + id + " location: " + location);
@@ -1074,10 +1085,7 @@ public class VolumeControlService extends ProfileService {
        offsets.setLocation(id, location);

        if (Flags.leaudioMultipleVocsInstancesApi()) {
            if (mCallbacks == null) {
                return;
            }

            synchronized (mCallbacks) {
                int n = mCallbacks.beginBroadcast();
                for (int i = 0; i < n; i++) {
                    try {
@@ -1091,6 +1099,7 @@ public class VolumeControlService extends ProfileService {
                mCallbacks.finishBroadcast();
            }
        }
    }

    void handleDeviceExtAudioDescriptionChanged(
            BluetoothDevice device, int id, String description) {
@@ -1104,10 +1113,7 @@ public class VolumeControlService extends ProfileService {
        offsets.setDescription(id, description);

        if (Flags.leaudioMultipleVocsInstancesApi()) {
            if (mCallbacks == null) {
                return;
            }

            synchronized (mCallbacks) {
                int n = mCallbacks.beginBroadcast();
                for (int i = 0; i < n; i++) {
                    try {
@@ -1121,6 +1127,7 @@ public class VolumeControlService extends ProfileService {
                mCallbacks.finishBroadcast();
            }
        }
    }

    void messageFromNative(VolumeControlStackEvent stackEvent) {
        Log.d(TAG, "messageFromNative: " + stackEvent);
@@ -1721,7 +1728,7 @@ public class VolumeControlService extends ProfileService {
            }

            enforceBluetoothPrivilegedPermission(service);
            postAndWait(service.mHandler, () -> service.mCallbacks.unregister(callback));
            postAndWait(service.mHandler, () -> service.unregisterCallback(callback));
        }
    }

+31 −31
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.bluetooth.le_audio;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doReturn;
@@ -34,7 +36,6 @@ import android.bluetooth.IBluetoothLeAudioCallback;
import android.bluetooth.IBluetoothLeBroadcastCallback;
import android.content.AttributionSource;
import android.os.ParcelUuid;
import android.os.RemoteCallbackList;
import android.platform.test.flag.junit.SetFlagsRule;

import androidx.test.InstrumentationRegistry;
@@ -69,9 +70,6 @@ public class LeAudioBinderTest {
    @Mock private DatabaseManager mDatabaseManager;
    @Mock private AudioRoutingManager mAudioRoutingManager;

    @Mock private RemoteCallbackList<IBluetoothLeAudioCallback> mLeAudioCallbacks;
    @Mock private RemoteCallbackList<IBluetoothLeBroadcastCallback> mBroadcastCallbacks;

    private LeAudioService.BluetoothLeAudioBinder mBinder;
    private BluetoothAdapter mAdapter;

@@ -96,8 +94,6 @@ public class LeAudioBinderTest {
        mLeAudioService.start();
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mBinder = new LeAudioService.BluetoothLeAudioBinder(mLeAudioService);
        mLeAudioService.mLeAudioCallbacks = mLeAudioCallbacks;
        mLeAudioService.mBroadcastCallbacks = mBroadcastCallbacks;
    }

    @After
@@ -291,39 +287,43 @@ public class LeAudioBinderTest {
    }

    @Test
    public void registerCallback() {
    public void registerUnregisterCallback() {
        synchronized (mLeAudioService.mLeAudioCallbacks) {
            IBluetoothLeAudioCallback callback = Mockito.mock(IBluetoothLeAudioCallback.class);
            doReturn(mBinder).when(callback).asBinder();

            AttributionSource source = new AttributionSource.Builder(0).build();

            assertThat(mLeAudioService.mLeAudioCallbacks.beginBroadcast()).isEqualTo(0);
            mLeAudioService.mLeAudioCallbacks.finishBroadcast();
            mBinder.registerCallback(callback, source);
        verify(mLeAudioService.mLeAudioCallbacks).register(callback);
    }

    @Test
    public void unregisterCallback() {
        IBluetoothLeAudioCallback callback = Mockito.mock(IBluetoothLeAudioCallback.class);
        AttributionSource source = new AttributionSource.Builder(0).build();
            assertThat(mLeAudioService.mLeAudioCallbacks.beginBroadcast()).isEqualTo(1);
            mLeAudioService.mLeAudioCallbacks.finishBroadcast();

            mBinder.unregisterCallback(callback, source);
        verify(mLeAudioService.mLeAudioCallbacks).unregister(callback);
            assertThat(mLeAudioService.mLeAudioCallbacks.beginBroadcast()).isEqualTo(0);
            mLeAudioService.mLeAudioCallbacks.finishBroadcast();
        }
    }

    @Test
    public void registerLeBroadcastCallback() {
        IBluetoothLeBroadcastCallback callback = Mockito.mock(IBluetoothLeBroadcastCallback.class);
    public void registerUnregisterLeBroadcastCallback() {
        synchronized (mLeAudioService.mBroadcastCallbacks) {
            IBluetoothLeBroadcastCallback callback =
                    Mockito.mock(IBluetoothLeBroadcastCallback.class);
            doReturn(mBinder).when(callback).asBinder();
            AttributionSource source = new AttributionSource.Builder(0).build();

            assertThat(mLeAudioService.mBroadcastCallbacks.beginBroadcast()).isEqualTo(0);
            mLeAudioService.mBroadcastCallbacks.finishBroadcast();
            mBinder.registerLeBroadcastCallback(callback, source);
        verify(mLeAudioService.mBroadcastCallbacks).register(callback);
    }

    @Test
    public void unregisterLeBroadcastCallback() {
        IBluetoothLeBroadcastCallback callback = Mockito.mock(IBluetoothLeBroadcastCallback.class);
        AttributionSource source = new AttributionSource.Builder(0).build();

            assertThat(mLeAudioService.mBroadcastCallbacks.beginBroadcast()).isEqualTo(1);
            mLeAudioService.mBroadcastCallbacks.finishBroadcast();
            mBinder.unregisterLeBroadcastCallback(callback, source);
        verify(mLeAudioService.mBroadcastCallbacks).unregister(callback);
            assertThat(mLeAudioService.mBroadcastCallbacks.beginBroadcast()).isEqualTo(0);
            mLeAudioService.mBroadcastCallbacks.finishBroadcast();
        }
    }

    @Test