Check callback exception in BluetoothLeBroadcastTest

Tag: #feature
Bug: 279233387
Test: cts pass
(cherry picked from https://android-review.googlesource.com/q/commit:a3102ac192ed96b105d0c7135a5351e9698ac709)
Merged-In: I16cbab0d7397d791073d13726bb9f3c853c057cf
Change-Id: I16cbab0d7397d791073d13726bb9f3c853c057cf
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeBroadcastTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeBroadcastTest.java
index dab84ca..dfb11de 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeBroadcastTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeBroadcastTest.java
@@ -26,6 +26,9 @@
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
@@ -55,6 +58,10 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
@@ -68,6 +75,7 @@
 public class BluetoothLeBroadcastTest {
     private static final String TAG = BluetoothLeBroadcastTest.class.getSimpleName();
 
+    private static final int BROADCAST_STARTED_TIMEOUT_MS = 500;
     private static final int PROXY_CONNECTION_TIMEOUT_MS = 500;  // ms timeout for Proxy Connect
 
     private static final String TEST_MAC_ADDRESS = "00:11:22:33:44:55";
@@ -99,6 +107,7 @@
 
     private Context mContext;
     private BluetoothAdapter mAdapter;
+    private Executor mExecutor;
 
     private BluetoothLeBroadcast mBluetoothLeBroadcast;
     private boolean mIsProfileReady;
@@ -117,6 +126,31 @@
 
     private BluetoothLeBroadcastMetadata mTestMetadata;
     private CountDownLatch mCallbackCountDownLatch;
+    private @Captor ArgumentCaptor<Integer> mBroadcastId;
+
+    @Mock
+    BluetoothLeBroadcast.Callback mCallback =
+            new BluetoothLeBroadcast.Callback() {
+                @Override
+                public void onBroadcastStarted(int reason, int broadcastId) {}
+                @Override
+                public void onBroadcastStartFailed(int reason) {}
+                @Override
+                public void onBroadcastStopped(int reason, int broadcastId) {}
+                @Override
+                public void onBroadcastStopFailed(int reason) {}
+                @Override
+                public void onPlaybackStarted(int reason, int broadcastId) {}
+                @Override
+                public void onPlaybackStopped(int reason, int broadcastId) {}
+                @Override
+                public void onBroadcastUpdated(int reason, int broadcastId) {}
+                @Override
+                public void onBroadcastUpdateFailed(int reason, int broadcastId) {}
+                @Override
+                public void onBroadcastMetadataChanged(int broadcastId,
+                        BluetoothLeBroadcastMetadata metadata) {}
+            };
 
     BluetoothLeBroadcastSubgroup createBroadcastSubgroup() {
         BluetoothLeAudioCodecConfigMetadata codecMetadata =
@@ -184,6 +218,9 @@
         Assume.assumeTrue(ApiLevelUtil.isAtLeast(Build.VERSION_CODES.TIRAMISU));
         Assume.assumeTrue(TestUtils.isBleSupported(mContext));
 
+        MockitoAnnotations.initMocks(this);
+        mExecutor = mContext.getMainExecutor();
+
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
         mAdapter = TestUtils.getBluetoothAdapterOrDie();
         assertTrue(BTAdapterUtils.enableAdapter(mAdapter, mContext));
@@ -260,40 +297,18 @@
         assertNotNull(mBluetoothLeBroadcast);
 
         Executor executor = mContext.getMainExecutor();
-        BluetoothLeBroadcast.Callback callback =
-                new BluetoothLeBroadcast.Callback() {
-                    @Override
-                    public void onBroadcastStarted(int reason, int broadcastId) {}
-                    @Override
-                    public void onBroadcastStartFailed(int reason) {}
-                    @Override
-                    public void onBroadcastStopped(int reason, int broadcastId) {}
-                    @Override
-                    public void onBroadcastStopFailed(int reason) {}
-                    @Override
-                    public void onPlaybackStarted(int reason, int broadcastId) {}
-                    @Override
-                    public void onPlaybackStopped(int reason, int broadcastId) {}
-                    @Override
-                    public void onBroadcastUpdated(int reason, int broadcastId) {}
-                    @Override
-                    public void onBroadcastUpdateFailed(int reason, int broadcastId) {}
-                    @Override
-                    public void onBroadcastMetadataChanged(int broadcastId,
-                            BluetoothLeBroadcastMetadata metadata) {}
-                };
 
         // Verify invalid parameters
         assertThrows(NullPointerException.class, () ->
-                mBluetoothLeBroadcast.registerCallback(null, callback));
+                mBluetoothLeBroadcast.registerCallback(null, mCallback));
         assertThrows(NullPointerException.class, () ->
                 mBluetoothLeBroadcast.registerCallback(executor, null));
         assertThrows(NullPointerException.class, () ->
                 mBluetoothLeBroadcast.unregisterCallback(null));
 
         // Verify valid parameters
-        mBluetoothLeBroadcast.registerCallback(executor, callback);
-        mBluetoothLeBroadcast.unregisterCallback(callback);
+        mBluetoothLeBroadcast.registerCallback(executor, mCallback);
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -451,7 +466,20 @@
         BluetoothLeAudioContentMetadata.Builder contentMetadataBuilder =
                 new BluetoothLeAudioContentMetadata.Builder();
         byte[] broadcastCode = {1, 2, 3, 4, 5, 6};
+
+        // Verifies that it throws exception when no callback is registered
+        assertThrows(IllegalStateException.class, () ->
+                mBluetoothLeBroadcast.startBroadcast(contentMetadataBuilder.build(),
+                        broadcastCode));
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
+
         mBluetoothLeBroadcast.startBroadcast(contentMetadataBuilder.build(), broadcastCode);
+        verify(mCallback, timeout(BROADCAST_STARTED_TIMEOUT_MS))
+                .onBroadcastStarted(eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST),
+                        mBroadcastId.capture());
+
+        mBluetoothLeBroadcast.stopBroadcast(mBroadcastId.getValue());
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -463,6 +491,7 @@
         BluetoothLeAudioContentMetadata.Builder contentMetadataBuilder =
                 new BluetoothLeAudioContentMetadata.Builder();
         byte[] broadcastCode = {1, 2, 3, 4, 5, 6};
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
 
         TestUtils.dropPermissionAsShellUid();
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT);
@@ -473,6 +502,7 @@
                         contentMetadataBuilder.build(), broadcastCode));
 
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -489,8 +519,17 @@
         for (BluetoothLeBroadcastSubgroupSettings setting : subgroupSettings) {
             broadcastSettingsBuilder.addSubgroupSettings(setting);
         }
+        // Verifies that it throws exception when no callback is registered
+        assertThrows(IllegalStateException.class, () ->
+                mBluetoothLeBroadcast.startBroadcast(broadcastSettingsBuilder.build()));
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
 
         mBluetoothLeBroadcast.startBroadcast(broadcastSettingsBuilder.build());
+        verify(mCallback, timeout(BROADCAST_STARTED_TIMEOUT_MS))
+                .onBroadcastStarted(eq(BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST),
+                        mBroadcastId.capture());
+        mBluetoothLeBroadcast.stopBroadcast(mBroadcastId.getValue());
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -508,6 +547,7 @@
         for (BluetoothLeBroadcastSubgroupSettings setting : subgroupSettings) {
             broadcastSettingsBuilder.addSubgroupSettings(setting);
         }
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
 
         TestUtils.dropPermissionAsShellUid();
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT);
@@ -518,6 +558,7 @@
                         broadcastSettingsBuilder.build()));
 
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -527,7 +568,13 @@
 
         BluetoothLeAudioContentMetadata.Builder contentMetadataBuilder =
                 new BluetoothLeAudioContentMetadata.Builder();
+        // Verifies that it throws exception when no callback is registered
+        assertThrows(IllegalStateException.class, () ->
+                mBluetoothLeBroadcast.updateBroadcast(1, contentMetadataBuilder.build()));
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
+
         mBluetoothLeBroadcast.updateBroadcast(1, contentMetadataBuilder.build());
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -538,6 +585,7 @@
 
         BluetoothLeAudioContentMetadata.Builder contentMetadataBuilder =
                 new BluetoothLeAudioContentMetadata.Builder();
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
 
         TestUtils.dropPermissionAsShellUid();
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT);
@@ -547,6 +595,7 @@
                 () -> mBluetoothLeBroadcast.updateBroadcast(1, contentMetadataBuilder.build()));
 
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -563,8 +612,13 @@
         for (BluetoothLeBroadcastSubgroupSettings setting : subgroupSettings) {
             broadcastSettingsBuilder.addSubgroupSettings(setting);
         }
+        // Verifies that it throws exception when no callback is registered
+        assertThrows(IllegalStateException.class, () ->
+                mBluetoothLeBroadcast.updateBroadcast(1, broadcastSettingsBuilder.build()));
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
 
         mBluetoothLeBroadcast.updateBroadcast(1, broadcastSettingsBuilder.build());
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -582,6 +636,7 @@
         for (BluetoothLeBroadcastSubgroupSettings setting : subgroupSettings) {
             broadcastSettingsBuilder.addSubgroupSettings(setting);
         }
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
 
         TestUtils.dropPermissionAsShellUid();
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT);
@@ -591,6 +646,7 @@
                 () -> mBluetoothLeBroadcast.updateBroadcast(1, broadcastSettingsBuilder.build()));
 
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -598,7 +654,13 @@
         assertTrue(waitForProfileConnect());
         assertNotNull(mBluetoothLeBroadcast);
 
+        // Verifies that it throws exception when no callback is registered
+        assertThrows(IllegalStateException.class, () ->  mBluetoothLeBroadcast.stopBroadcast(1));
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
+
         mBluetoothLeBroadcast.stopBroadcast(1);
+
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -607,6 +669,8 @@
         assertTrue(waitForProfileConnect());
         assertNotNull(mBluetoothLeBroadcast);
 
+        mBluetoothLeBroadcast.registerCallback(mExecutor, mCallback);
+
         TestUtils.dropPermissionAsShellUid();
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT);
 
@@ -615,6 +679,7 @@
                 () -> mBluetoothLeBroadcast.stopBroadcast(1));
 
         TestUtils.adoptPermissionAsShellUid(BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED);
+        mBluetoothLeBroadcast.unregisterCallback(mCallback);
     }
 
     @Test
@@ -646,8 +711,6 @@
         assertTrue(waitForProfileConnect());
         assertNotNull(mBluetoothLeBroadcast);
 
-        assertTrue(BTAdapterUtils.disableAdapter(mAdapter, mContext));
-
         List<BluetoothLeBroadcastMetadata> metaList =
                 mBluetoothLeBroadcast.getAllBroadcastMetadata();
         assertTrue(metaList.isEmpty());