Loading android/app/jni/com_android_bluetooth_le_audio.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -872,6 +872,7 @@ jobject prepareBluetoothLeBroadcastMetadataObject( (jint)broadcast_metadata.adv_sid, (jint)broadcast_metadata.broadcast_id, (jint)broadcast_metadata.pa_interval, broadcast_metadata.broadcast_code ? true : false, false, nullptr, broadcast_metadata.broadcast_code ? code.get() : nullptr, (jint)broadcast_metadata.basic_audio_announcement.presentation_delay, subgroup_list_obj.get()); Loading Loading @@ -990,9 +991,10 @@ static void BroadcasterClassInitNative(JNIEnv* env, jclass clazz) { jclass jniBluetoothLeBroadcastMetadataClass = env->FindClass("android/bluetooth/BluetoothLeBroadcastMetadata"); android_bluetooth_BluetoothLeBroadcastMetadata.constructor = env->GetMethodID( jniBluetoothLeBroadcastMetadataClass, "<init>", "(ILandroid/bluetooth/BluetoothDevice;IIIZ[BILjava/util/List;)V"); android_bluetooth_BluetoothLeBroadcastMetadata.constructor = env->GetMethodID(jniBluetoothLeBroadcastMetadataClass, "<init>", "(ILandroid/bluetooth/BluetoothDevice;IIIZZLjava/lang/" "String;[BILjava/util/List;)V"); } static void BroadcasterInitNative(JNIEnv* env, jobject object) { Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +112 −24 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastSettings; import android.bluetooth.BluetoothLeBroadcastSubgroupSettings; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUuid; Loading Loading @@ -727,14 +729,17 @@ public class LeAudioService extends ProfileService { } /** * Creates LeAudio Broadcast instance. * @param metadata metadata buffer with TLVs * Creates LeAudio Broadcast instance with BluetoothLeBroadcastSettings. * * @param broadcastSettings broadcast settings for this broadcast source */ public void createBroadcast(BluetoothLeAudioContentMetadata metadata, byte[] broadcastCode) { public void createBroadcast(BluetoothLeBroadcastSettings broadcastSettings) { if (mLeAudioBroadcasterNativeInterface == null) { Log.w(TAG, "Native interface not available."); return; } byte[] broadcastCode = broadcastSettings.getBroadcastCode(); boolean isEncrypted = (broadcastCode != null) && (broadcastCode.length != 0); if (isEncrypted) { if ((broadcastCode.length > 16) || (broadcastCode.length < 4)) { Loading @@ -742,10 +747,24 @@ public class LeAudioService extends ProfileService { return; } } Log.i(TAG, "createBroadcast: isEncrypted=" + (isEncrypted ? "true" : "false")); mLeAudioBroadcasterNativeInterface.createBroadcast(metadata.getRawMetadata(), broadcastCode); List<BluetoothLeBroadcastSubgroupSettings> settings = broadcastSettings.getSubgroupSettings(); if (settings == null || settings.size() < 1) { Log.d(TAG, "subgroup settings is not valid value"); return; } // only one subgroup is supported now // TODO(b/267783231): Extend LE broadcast support for multi subgroup BluetoothLeAudioContentMetadata contentMetadata = settings.get(0).getContentMetadata(); if (contentMetadata == null) { Log.d(TAG, "contentMetadata cannot be null"); return; } mLeAudioBroadcasterNativeInterface.createBroadcast( contentMetadata.getRawMetadata(), broadcastCode); } /** Loading @@ -762,23 +781,39 @@ public class LeAudioService extends ProfileService { } /** * Updates LeAudio Broadcast instance metadata. * Updates LeAudio broadcast instance metadata. * * @param broadcastId broadcast instance identifier * @param metadata metadata for the default Broadcast subgroup * @param broadcastSettings broadcast settings for this broadcast source */ public void updateBroadcast(int broadcastId, BluetoothLeAudioContentMetadata metadata) { public void updateBroadcast(int broadcastId, BluetoothLeBroadcastSettings broadcastSettings) { if (mLeAudioBroadcasterNativeInterface == null) { Log.w(TAG, "Native interface not available."); return; } if (!mBroadcastStateMap.containsKey(broadcastId)) { notifyBroadcastUpdateFailed(broadcastId, BluetoothStatusCodes.ERROR_LE_BROADCAST_INVALID_BROADCAST_ID); notifyBroadcastUpdateFailed( broadcastId, BluetoothStatusCodes.ERROR_LE_BROADCAST_INVALID_BROADCAST_ID); return; } List<BluetoothLeBroadcastSubgroupSettings> settings = broadcastSettings.getSubgroupSettings(); if (settings == null || settings.size() < 1) { Log.d(TAG, "subgroup settings is not valid value"); return; } // only one subgroup is supported now // TODO(b/267783231): Extend LE broadcast support for multi subgroup BluetoothLeAudioContentMetadata contentMetadata = settings.get(0).getContentMetadata(); if (contentMetadata == null) { Log.d(TAG, "contentMetadata cannot be null"); return; } if (DBG) Log.d(TAG, "updateBroadcast"); mLeAudioBroadcasterNativeInterface.updateMetadata(broadcastId, metadata.getRawMetadata()); mLeAudioBroadcasterNativeInterface.updateMetadata( broadcastId, contentMetadata.getRawMetadata()); } /** Loading Loading @@ -845,6 +880,26 @@ public class LeAudioService extends ProfileService { return 1; } /** * Get the maximum number of supported streams per broadcast. * * @return number of supported streams per broadcast */ public int getMaximumStreamsPerBroadcast() { /* TODO: This is currently fixed to 1 */ return 1; } /** * Get the maximum number of supported subgroups per broadcast. * * @return number of supported subgroups per broadcast */ public int getMaximumSubgroupsPerBroadcast() { /* TODO: This is currently fixed to 1 */ return 1; } private BluetoothDevice getFirstDeviceFromGroup(Integer groupId) { if (groupId == LE_AUDIO_GROUP_ID_INVALID) { return null; Loading Loading @@ -2173,12 +2228,11 @@ public class LeAudioService extends ProfileService { } /** * This function is called when the framework registers * a callback with the service for this first time. * This is used as an indication that Bluetooth has been enabled. * This function is called when the framework registers a callback with the service for this * first time. This is used as an indication that Bluetooth has been enabled. * * It is used to authorize all known LeAudio devices in the services * which requires that e.g. GMCS * <p>It is used to authorize all known LeAudio devices in the services which requires that e.g. * GMCS */ @VisibleForTesting void handleBluetoothEnabled() { Loading Loading @@ -3109,12 +3163,12 @@ public class LeAudioService extends ProfileService { } @Override public void startBroadcast(BluetoothLeAudioContentMetadata contentMetadata, byte[] broadcastCode, AttributionSource source) { public void startBroadcast( BluetoothLeBroadcastSettings broadcastSettings, AttributionSource source) { LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); service.createBroadcast(contentMetadata, broadcastCode); service.createBroadcast(broadcastSettings); } } Loading @@ -3128,12 +3182,14 @@ public class LeAudioService extends ProfileService { } @Override public void updateBroadcast(int broadcastId, BluetoothLeAudioContentMetadata contentMetadata, AttributionSource source) { public void updateBroadcast( int broadcastId, BluetoothLeBroadcastSettings broadcastSettings, AttributionSource source) { LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); service.updateBroadcast(broadcastId, contentMetadata); service.updateBroadcast(broadcastId, broadcastSettings); } } Loading Loading @@ -3185,6 +3241,38 @@ public class LeAudioService extends ProfileService { } } @Override public void getMaximumStreamsPerBroadcast( AttributionSource source, SynchronousResultReceiver receiver) { try { int result = 0; LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); result = service.getMaximumStreamsPerBroadcast(); } receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void getMaximumSubgroupsPerBroadcast( AttributionSource source, SynchronousResultReceiver receiver) { try { int result = 0; LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); result = service.getMaximumSubgroupsPerBroadcast(); } receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void getCodecStatus(int groupId, AttributionSource source, SynchronousResultReceiver receiver) { Loading android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java +48 −9 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastSettings; import android.bluetooth.BluetoothLeBroadcastSubgroupSettings; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothProfile; import android.bluetooth.IBluetoothLeAudioCallback; Loading Loading @@ -56,6 +58,10 @@ public class LeAudioBinderTest { private LeAudioService.BluetoothLeAudioBinder mBinder; private BluetoothAdapter mAdapter; private static final String TEST_BROADCAST_NAME = "TEST"; private static final int TEST_QUALITY = BluetoothLeBroadcastSubgroupSettings.QUALITY_STANDARD; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Loading Loading @@ -298,13 +304,11 @@ public class LeAudioBinderTest { @Test public void startBroadcast() { BluetoothLeAudioContentMetadata metadata = new BluetoothLeAudioContentMetadata.Builder().build(); byte[] code = new byte[] { 0x00 }; BluetoothLeBroadcastSettings broadcastSettings = buildBroadcastSettingsFromMetadata(); AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.startBroadcast(metadata, code, source); verify(mMockService).createBroadcast(metadata, code); mBinder.startBroadcast(broadcastSettings, source); verify(mMockService).createBroadcast(broadcastSettings); } @Test Loading @@ -319,12 +323,11 @@ public class LeAudioBinderTest { @Test public void updateBroadcast() { int id = 1; BluetoothLeAudioContentMetadata metadata = new BluetoothLeAudioContentMetadata.Builder().build(); BluetoothLeBroadcastSettings broadcastSettings = buildBroadcastSettingsFromMetadata(); AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.updateBroadcast(id, metadata, source); verify(mMockService).updateBroadcast(id, metadata); mBinder.updateBroadcast(id, broadcastSettings, source); verify(mMockService).updateBroadcast(id, broadcastSettings); } @Test Loading Loading @@ -358,6 +361,24 @@ public class LeAudioBinderTest { verify(mMockService).getMaximumNumberOfBroadcasts(); } @Test public void getMaximumStreamsPerBroadcast() { AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); mBinder.getMaximumStreamsPerBroadcast(source, recv); verify(mMockService).getMaximumStreamsPerBroadcast(); } @Test public void getMaximumSubgroupsPerBroadcast() { AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); mBinder.getMaximumSubgroupsPerBroadcast(source, recv); verify(mMockService).getMaximumSubgroupsPerBroadcast(); } @Test public void getCodecStatus() { int groupId = 1; Loading @@ -381,4 +402,22 @@ public class LeAudioBinderTest { mBinder.setCodecConfigPreference(groupId, inputConfig, outputConfig, source); verify(mMockService).setCodecConfigPreference(groupId, inputConfig, outputConfig); } private BluetoothLeBroadcastSettings buildBroadcastSettingsFromMetadata() { BluetoothLeAudioContentMetadata metadata = new BluetoothLeAudioContentMetadata.Builder().build(); BluetoothLeBroadcastSubgroupSettings.Builder subgroupBuilder = new BluetoothLeBroadcastSubgroupSettings.Builder() .setPreferredQuality(TEST_QUALITY) .setContentMetadata(metadata); BluetoothLeBroadcastSettings.Builder builder = new BluetoothLeBroadcastSettings.Builder() .setPublicBroadcast(false) .setBroadcastName(TEST_BROADCAST_NAME) .setBroadcastCode(null); // builder expect at least one subgroup setting builder.addSubgroupSettings(subgroupBuilder.build()); return builder.build(); } } android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java +20 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.le_audio; import static org.mockito.Mockito.*; import android.annotation.Nullable; import android.bluetooth.*; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -243,7 +244,7 @@ public class LeAudioBroadcastServiceTest { void verifyBroadcastStarted(int broadcastId, byte[] code, BluetoothLeAudioContentMetadata meta) { mService.createBroadcast(meta, code); mService.createBroadcast(buildBroadcastSettingsFromMetadata(meta, code)); verify(mNativeInterface, times(1)).createBroadcast(eq(meta.getRawMetadata()), eq(code)); Loading Loading @@ -325,7 +326,7 @@ public class LeAudioBroadcastServiceTest { meta_builder.setLanguage("deu"); meta_builder.setProgramInfo("Public broadcast info"); BluetoothLeAudioContentMetadata meta = meta_builder.build(); mService.createBroadcast(meta, code); mService.createBroadcast(buildBroadcastSettingsFromMetadata(meta, code)); verify(mNativeInterface, times(1)).createBroadcast(eq(meta.getRawMetadata()), eq(code)); Loading Loading @@ -371,7 +372,8 @@ public class LeAudioBroadcastServiceTest { new BluetoothLeAudioContentMetadata.Builder(); meta_builder.setLanguage("eng"); meta_builder.setProgramInfo("Public broadcast info"); mService.updateBroadcast(broadcastId, meta_builder.build()); mService.updateBroadcast(broadcastId, buildBroadcastSettingsFromMetadata(meta_builder.build(), null)); Assert.assertFalse(mOnBroadcastUpdatedCalled); Assert.assertTrue(mOnBroadcastUpdateFailedCalled); } Loading Loading @@ -430,7 +432,7 @@ public class LeAudioBroadcastServiceTest { meta_builder.setLanguage("ENG"); meta_builder.setProgramInfo("Public broadcast info"); BluetoothLeAudioContentMetadata meta = meta_builder.build(); mService.createBroadcast(meta, code); mService.createBroadcast(buildBroadcastSettingsFromMetadata(meta, code)); // Inject metadata stack event and verify if getter API works as expected LeAudioStackEvent state_event = Loading @@ -456,4 +458,18 @@ public class LeAudioBroadcastServiceTest { } } private BluetoothLeBroadcastSettings buildBroadcastSettingsFromMetadata( BluetoothLeAudioContentMetadata contentMetadata, @Nullable byte[] broadcastCode) { BluetoothLeBroadcastSubgroupSettings.Builder subgroupBuilder = new BluetoothLeBroadcastSubgroupSettings.Builder() .setContentMetadata(contentMetadata); BluetoothLeBroadcastSettings.Builder builder = new BluetoothLeBroadcastSettings.Builder() .setPublicBroadcast(false) .setBroadcastCode(broadcastCode); // builder expect at least one subgroup setting builder.addSubgroupSettings(subgroupBuilder.build()); return builder.build(); } } android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +2 −3 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; import android.media.BluetoothProfileConnectionInfo; import android.os.Parcel; import android.os.ParcelUuid; import androidx.test.InstrumentationRegistry; Loading @@ -56,7 +55,6 @@ import androidx.test.filters.MediumTest; import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ServiceFactory; Loading @@ -66,7 +64,6 @@ import com.android.bluetooth.mcp.McpService; import com.android.bluetooth.vc.VolumeControlService; import org.junit.After; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading Loading @@ -1558,6 +1555,8 @@ public class LeAudioServiceTest { @Test public void testDefaultValuesOfSeveralGetters() { assertThat(mService.getMaximumNumberOfBroadcasts()).isEqualTo(1); assertThat(mService.getMaximumStreamsPerBroadcast()).isEqualTo(1); assertThat(mService.getMaximumSubgroupsPerBroadcast()).isEqualTo(1); assertThat(mService.isPlaying(100)).isFalse(); assertThat(mService.isValidDeviceGroup(LE_AUDIO_GROUP_ID_INVALID)).isFalse(); } Loading Loading
android/app/jni/com_android_bluetooth_le_audio.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -872,6 +872,7 @@ jobject prepareBluetoothLeBroadcastMetadataObject( (jint)broadcast_metadata.adv_sid, (jint)broadcast_metadata.broadcast_id, (jint)broadcast_metadata.pa_interval, broadcast_metadata.broadcast_code ? true : false, false, nullptr, broadcast_metadata.broadcast_code ? code.get() : nullptr, (jint)broadcast_metadata.basic_audio_announcement.presentation_delay, subgroup_list_obj.get()); Loading Loading @@ -990,9 +991,10 @@ static void BroadcasterClassInitNative(JNIEnv* env, jclass clazz) { jclass jniBluetoothLeBroadcastMetadataClass = env->FindClass("android/bluetooth/BluetoothLeBroadcastMetadata"); android_bluetooth_BluetoothLeBroadcastMetadata.constructor = env->GetMethodID( jniBluetoothLeBroadcastMetadataClass, "<init>", "(ILandroid/bluetooth/BluetoothDevice;IIIZ[BILjava/util/List;)V"); android_bluetooth_BluetoothLeBroadcastMetadata.constructor = env->GetMethodID(jniBluetoothLeBroadcastMetadataClass, "<init>", "(ILandroid/bluetooth/BluetoothDevice;IIIZZLjava/lang/" "String;[BILjava/util/List;)V"); } static void BroadcasterInitNative(JNIEnv* env, jobject object) { Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +112 −24 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastSettings; import android.bluetooth.BluetoothLeBroadcastSubgroupSettings; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.bluetooth.BluetoothUuid; Loading Loading @@ -727,14 +729,17 @@ public class LeAudioService extends ProfileService { } /** * Creates LeAudio Broadcast instance. * @param metadata metadata buffer with TLVs * Creates LeAudio Broadcast instance with BluetoothLeBroadcastSettings. * * @param broadcastSettings broadcast settings for this broadcast source */ public void createBroadcast(BluetoothLeAudioContentMetadata metadata, byte[] broadcastCode) { public void createBroadcast(BluetoothLeBroadcastSettings broadcastSettings) { if (mLeAudioBroadcasterNativeInterface == null) { Log.w(TAG, "Native interface not available."); return; } byte[] broadcastCode = broadcastSettings.getBroadcastCode(); boolean isEncrypted = (broadcastCode != null) && (broadcastCode.length != 0); if (isEncrypted) { if ((broadcastCode.length > 16) || (broadcastCode.length < 4)) { Loading @@ -742,10 +747,24 @@ public class LeAudioService extends ProfileService { return; } } Log.i(TAG, "createBroadcast: isEncrypted=" + (isEncrypted ? "true" : "false")); mLeAudioBroadcasterNativeInterface.createBroadcast(metadata.getRawMetadata(), broadcastCode); List<BluetoothLeBroadcastSubgroupSettings> settings = broadcastSettings.getSubgroupSettings(); if (settings == null || settings.size() < 1) { Log.d(TAG, "subgroup settings is not valid value"); return; } // only one subgroup is supported now // TODO(b/267783231): Extend LE broadcast support for multi subgroup BluetoothLeAudioContentMetadata contentMetadata = settings.get(0).getContentMetadata(); if (contentMetadata == null) { Log.d(TAG, "contentMetadata cannot be null"); return; } mLeAudioBroadcasterNativeInterface.createBroadcast( contentMetadata.getRawMetadata(), broadcastCode); } /** Loading @@ -762,23 +781,39 @@ public class LeAudioService extends ProfileService { } /** * Updates LeAudio Broadcast instance metadata. * Updates LeAudio broadcast instance metadata. * * @param broadcastId broadcast instance identifier * @param metadata metadata for the default Broadcast subgroup * @param broadcastSettings broadcast settings for this broadcast source */ public void updateBroadcast(int broadcastId, BluetoothLeAudioContentMetadata metadata) { public void updateBroadcast(int broadcastId, BluetoothLeBroadcastSettings broadcastSettings) { if (mLeAudioBroadcasterNativeInterface == null) { Log.w(TAG, "Native interface not available."); return; } if (!mBroadcastStateMap.containsKey(broadcastId)) { notifyBroadcastUpdateFailed(broadcastId, BluetoothStatusCodes.ERROR_LE_BROADCAST_INVALID_BROADCAST_ID); notifyBroadcastUpdateFailed( broadcastId, BluetoothStatusCodes.ERROR_LE_BROADCAST_INVALID_BROADCAST_ID); return; } List<BluetoothLeBroadcastSubgroupSettings> settings = broadcastSettings.getSubgroupSettings(); if (settings == null || settings.size() < 1) { Log.d(TAG, "subgroup settings is not valid value"); return; } // only one subgroup is supported now // TODO(b/267783231): Extend LE broadcast support for multi subgroup BluetoothLeAudioContentMetadata contentMetadata = settings.get(0).getContentMetadata(); if (contentMetadata == null) { Log.d(TAG, "contentMetadata cannot be null"); return; } if (DBG) Log.d(TAG, "updateBroadcast"); mLeAudioBroadcasterNativeInterface.updateMetadata(broadcastId, metadata.getRawMetadata()); mLeAudioBroadcasterNativeInterface.updateMetadata( broadcastId, contentMetadata.getRawMetadata()); } /** Loading Loading @@ -845,6 +880,26 @@ public class LeAudioService extends ProfileService { return 1; } /** * Get the maximum number of supported streams per broadcast. * * @return number of supported streams per broadcast */ public int getMaximumStreamsPerBroadcast() { /* TODO: This is currently fixed to 1 */ return 1; } /** * Get the maximum number of supported subgroups per broadcast. * * @return number of supported subgroups per broadcast */ public int getMaximumSubgroupsPerBroadcast() { /* TODO: This is currently fixed to 1 */ return 1; } private BluetoothDevice getFirstDeviceFromGroup(Integer groupId) { if (groupId == LE_AUDIO_GROUP_ID_INVALID) { return null; Loading Loading @@ -2173,12 +2228,11 @@ public class LeAudioService extends ProfileService { } /** * This function is called when the framework registers * a callback with the service for this first time. * This is used as an indication that Bluetooth has been enabled. * This function is called when the framework registers a callback with the service for this * first time. This is used as an indication that Bluetooth has been enabled. * * It is used to authorize all known LeAudio devices in the services * which requires that e.g. GMCS * <p>It is used to authorize all known LeAudio devices in the services which requires that e.g. * GMCS */ @VisibleForTesting void handleBluetoothEnabled() { Loading Loading @@ -3109,12 +3163,12 @@ public class LeAudioService extends ProfileService { } @Override public void startBroadcast(BluetoothLeAudioContentMetadata contentMetadata, byte[] broadcastCode, AttributionSource source) { public void startBroadcast( BluetoothLeBroadcastSettings broadcastSettings, AttributionSource source) { LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); service.createBroadcast(contentMetadata, broadcastCode); service.createBroadcast(broadcastSettings); } } Loading @@ -3128,12 +3182,14 @@ public class LeAudioService extends ProfileService { } @Override public void updateBroadcast(int broadcastId, BluetoothLeAudioContentMetadata contentMetadata, AttributionSource source) { public void updateBroadcast( int broadcastId, BluetoothLeBroadcastSettings broadcastSettings, AttributionSource source) { LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); service.updateBroadcast(broadcastId, contentMetadata); service.updateBroadcast(broadcastId, broadcastSettings); } } Loading Loading @@ -3185,6 +3241,38 @@ public class LeAudioService extends ProfileService { } } @Override public void getMaximumStreamsPerBroadcast( AttributionSource source, SynchronousResultReceiver receiver) { try { int result = 0; LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); result = service.getMaximumStreamsPerBroadcast(); } receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void getMaximumSubgroupsPerBroadcast( AttributionSource source, SynchronousResultReceiver receiver) { try { int result = 0; LeAudioService service = getService(source); if (service != null) { enforceBluetoothPrivilegedPermission(service); result = service.getMaximumSubgroupsPerBroadcast(); } receiver.send(result); } catch (RuntimeException e) { receiver.propagateException(e); } } @Override public void getCodecStatus(int groupId, AttributionSource source, SynchronousResultReceiver receiver) { Loading
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBinderTest.java +48 −9 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothLeAudioCodecConfig; import android.bluetooth.BluetoothLeAudioCodecStatus; import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastSettings; import android.bluetooth.BluetoothLeBroadcastSubgroupSettings; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothProfile; import android.bluetooth.IBluetoothLeAudioCallback; Loading Loading @@ -56,6 +58,10 @@ public class LeAudioBinderTest { private LeAudioService.BluetoothLeAudioBinder mBinder; private BluetoothAdapter mAdapter; private static final String TEST_BROADCAST_NAME = "TEST"; private static final int TEST_QUALITY = BluetoothLeBroadcastSubgroupSettings.QUALITY_STANDARD; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Loading Loading @@ -298,13 +304,11 @@ public class LeAudioBinderTest { @Test public void startBroadcast() { BluetoothLeAudioContentMetadata metadata = new BluetoothLeAudioContentMetadata.Builder().build(); byte[] code = new byte[] { 0x00 }; BluetoothLeBroadcastSettings broadcastSettings = buildBroadcastSettingsFromMetadata(); AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.startBroadcast(metadata, code, source); verify(mMockService).createBroadcast(metadata, code); mBinder.startBroadcast(broadcastSettings, source); verify(mMockService).createBroadcast(broadcastSettings); } @Test Loading @@ -319,12 +323,11 @@ public class LeAudioBinderTest { @Test public void updateBroadcast() { int id = 1; BluetoothLeAudioContentMetadata metadata = new BluetoothLeAudioContentMetadata.Builder().build(); BluetoothLeBroadcastSettings broadcastSettings = buildBroadcastSettingsFromMetadata(); AttributionSource source = new AttributionSource.Builder(0).build(); mBinder.updateBroadcast(id, metadata, source); verify(mMockService).updateBroadcast(id, metadata); mBinder.updateBroadcast(id, broadcastSettings, source); verify(mMockService).updateBroadcast(id, broadcastSettings); } @Test Loading Loading @@ -358,6 +361,24 @@ public class LeAudioBinderTest { verify(mMockService).getMaximumNumberOfBroadcasts(); } @Test public void getMaximumStreamsPerBroadcast() { AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); mBinder.getMaximumStreamsPerBroadcast(source, recv); verify(mMockService).getMaximumStreamsPerBroadcast(); } @Test public void getMaximumSubgroupsPerBroadcast() { AttributionSource source = new AttributionSource.Builder(0).build(); final SynchronousResultReceiver<Integer> recv = SynchronousResultReceiver.get(); mBinder.getMaximumSubgroupsPerBroadcast(source, recv); verify(mMockService).getMaximumSubgroupsPerBroadcast(); } @Test public void getCodecStatus() { int groupId = 1; Loading @@ -381,4 +402,22 @@ public class LeAudioBinderTest { mBinder.setCodecConfigPreference(groupId, inputConfig, outputConfig, source); verify(mMockService).setCodecConfigPreference(groupId, inputConfig, outputConfig); } private BluetoothLeBroadcastSettings buildBroadcastSettingsFromMetadata() { BluetoothLeAudioContentMetadata metadata = new BluetoothLeAudioContentMetadata.Builder().build(); BluetoothLeBroadcastSubgroupSettings.Builder subgroupBuilder = new BluetoothLeBroadcastSubgroupSettings.Builder() .setPreferredQuality(TEST_QUALITY) .setContentMetadata(metadata); BluetoothLeBroadcastSettings.Builder builder = new BluetoothLeBroadcastSettings.Builder() .setPublicBroadcast(false) .setBroadcastName(TEST_BROADCAST_NAME) .setBroadcastCode(null); // builder expect at least one subgroup setting builder.addSubgroupSettings(subgroupBuilder.build()); return builder.build(); } }
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioBroadcastServiceTest.java +20 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.bluetooth.le_audio; import static org.mockito.Mockito.*; import android.annotation.Nullable; import android.bluetooth.*; import android.content.BroadcastReceiver; import android.content.Context; Loading Loading @@ -243,7 +244,7 @@ public class LeAudioBroadcastServiceTest { void verifyBroadcastStarted(int broadcastId, byte[] code, BluetoothLeAudioContentMetadata meta) { mService.createBroadcast(meta, code); mService.createBroadcast(buildBroadcastSettingsFromMetadata(meta, code)); verify(mNativeInterface, times(1)).createBroadcast(eq(meta.getRawMetadata()), eq(code)); Loading Loading @@ -325,7 +326,7 @@ public class LeAudioBroadcastServiceTest { meta_builder.setLanguage("deu"); meta_builder.setProgramInfo("Public broadcast info"); BluetoothLeAudioContentMetadata meta = meta_builder.build(); mService.createBroadcast(meta, code); mService.createBroadcast(buildBroadcastSettingsFromMetadata(meta, code)); verify(mNativeInterface, times(1)).createBroadcast(eq(meta.getRawMetadata()), eq(code)); Loading Loading @@ -371,7 +372,8 @@ public class LeAudioBroadcastServiceTest { new BluetoothLeAudioContentMetadata.Builder(); meta_builder.setLanguage("eng"); meta_builder.setProgramInfo("Public broadcast info"); mService.updateBroadcast(broadcastId, meta_builder.build()); mService.updateBroadcast(broadcastId, buildBroadcastSettingsFromMetadata(meta_builder.build(), null)); Assert.assertFalse(mOnBroadcastUpdatedCalled); Assert.assertTrue(mOnBroadcastUpdateFailedCalled); } Loading Loading @@ -430,7 +432,7 @@ public class LeAudioBroadcastServiceTest { meta_builder.setLanguage("ENG"); meta_builder.setProgramInfo("Public broadcast info"); BluetoothLeAudioContentMetadata meta = meta_builder.build(); mService.createBroadcast(meta, code); mService.createBroadcast(buildBroadcastSettingsFromMetadata(meta, code)); // Inject metadata stack event and verify if getter API works as expected LeAudioStackEvent state_event = Loading @@ -456,4 +458,18 @@ public class LeAudioBroadcastServiceTest { } } private BluetoothLeBroadcastSettings buildBroadcastSettingsFromMetadata( BluetoothLeAudioContentMetadata contentMetadata, @Nullable byte[] broadcastCode) { BluetoothLeBroadcastSubgroupSettings.Builder subgroupBuilder = new BluetoothLeBroadcastSubgroupSettings.Builder() .setContentMetadata(contentMetadata); BluetoothLeBroadcastSettings.Builder builder = new BluetoothLeBroadcastSettings.Builder() .setPublicBroadcast(false) .setBroadcastCode(broadcastCode); // builder expect at least one subgroup setting builder.addSubgroupSettings(subgroupBuilder.build()); return builder.build(); } }
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioServiceTest.java +2 −3 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.media.AudioManager; import android.media.BluetoothProfileConnectionInfo; import android.os.Parcel; import android.os.ParcelUuid; import androidx.test.InstrumentationRegistry; Loading @@ -56,7 +55,6 @@ import androidx.test.filters.MediumTest; import androidx.test.rule.ServiceTestRule; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ServiceFactory; Loading @@ -66,7 +64,6 @@ import com.android.bluetooth.mcp.McpService; import com.android.bluetooth.vc.VolumeControlService; import org.junit.After; import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading Loading @@ -1558,6 +1555,8 @@ public class LeAudioServiceTest { @Test public void testDefaultValuesOfSeveralGetters() { assertThat(mService.getMaximumNumberOfBroadcasts()).isEqualTo(1); assertThat(mService.getMaximumStreamsPerBroadcast()).isEqualTo(1); assertThat(mService.getMaximumSubgroupsPerBroadcast()).isEqualTo(1); assertThat(mService.isPlaying(100)).isFalse(); assertThat(mService.isValidDeviceGroup(LE_AUDIO_GROUP_ID_INVALID)).isFalse(); } Loading