Loading android/app/jni/com_android_bluetooth_le_audio.cpp +138 −19 Original line number Diff line number Diff line Loading @@ -27,8 +27,12 @@ using bluetooth::le_audio::BroadcastId; using bluetooth::le_audio::BroadcastState; using bluetooth::le_audio::btle_audio_bits_per_sample_index_t; using bluetooth::le_audio::btle_audio_channel_count_index_t; using bluetooth::le_audio::btle_audio_codec_config_t; using bluetooth::le_audio::btle_audio_codec_index_t; using bluetooth::le_audio::btle_audio_frame_duration_index_t; using bluetooth::le_audio::btle_audio_sample_rate_index_t; using bluetooth::le_audio::ConnectionState; using bluetooth::le_audio::GroupNodeStatus; using bluetooth::le_audio::GroupStatus; Loading @@ -45,7 +49,8 @@ static jmethodID method_onGroupNodeStatus; static jmethodID method_onAudioConf; static jmethodID method_onSinkAudioLocationAvailable; static jmethodID method_onAudioLocalCodecCapabilities; static jmethodID method_onAudioGroupCodecConf; static jmethodID method_onAudioGroupCurrentCodecConf; static jmethodID method_onAudioGroupSelectableCodecConf; static jmethodID method_onHealthBasedRecommendationAction; static jmethodID method_onHealthBasedGroupRecommendationAction; Loading @@ -53,6 +58,12 @@ static struct { jclass clazz; jmethodID constructor; jmethodID getCodecType; jmethodID getSampleRate; jmethodID getBitsPerSample; jmethodID getChannelCount; jmethodID getFrameDuration; jmethodID getOctetsPerFrame; jmethodID getCodecPriority; } android_bluetooth_BluetoothLeAudioCodecConfig; static struct { Loading Loading @@ -99,10 +110,21 @@ static std::shared_timed_mutex callbacks_mutex; jobject prepareCodecConfigObj(JNIEnv* env, btle_audio_codec_config_t codecConfig) { jobject codecConfigObj = env->NewObject(android_bluetooth_BluetoothLeAudioCodecConfig.clazz, LOG(INFO) << __func__ << "ct: " << codecConfig.codec_type << ", codec_priority: " << codecConfig.codec_priority << ", sample_rate: " << codecConfig.sample_rate << ", bits_per_sample: " << codecConfig.bits_per_sample << ", channel_count: " << codecConfig.channel_count << ", frame_duration: " << codecConfig.frame_duration << ", octets_per_frame: " << codecConfig.octets_per_frame; jobject codecConfigObj = env->NewObject( android_bluetooth_BluetoothLeAudioCodecConfig.clazz, android_bluetooth_BluetoothLeAudioCodecConfig.constructor, (jint)codecConfig.codec_type, 0, 0, 0, 0, 0, 0, 0, 0); (jint)codecConfig.codec_type, (jint)codecConfig.codec_priority, (jint)codecConfig.sample_rate, (jint)codecConfig.bits_per_sample, (jint)codecConfig.channel_count, (jint)codecConfig.frame_duration, (jint)codecConfig.octets_per_frame, 0, 0); return codecConfigObj; } Loading Loading @@ -247,12 +269,9 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { localInputCapCodecConfigArray, localOutputCapCodecConfigArray); } void OnAudioGroupCodecConf( void OnAudioGroupCurrentCodecConf( int group_id, btle_audio_codec_config_t input_codec_conf, btle_audio_codec_config_t /* output_codec_conf */, std::vector<btle_audio_codec_config_t> input_selectable_codec_conf, std::vector<btle_audio_codec_config_t> output_selectable_codec_conf) override { btle_audio_codec_config_t output_codec_conf) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); Loading @@ -262,15 +281,31 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { jobject inputCodecConfigObj = prepareCodecConfigObj(sCallbackEnv.get(), input_codec_conf); jobject outputCodecConfigObj = prepareCodecConfigObj(sCallbackEnv.get(), input_codec_conf); prepareCodecConfigObj(sCallbackEnv.get(), output_codec_conf); sCallbackEnv->CallVoidMethod( mCallbacksObj, method_onAudioGroupCurrentCodecConf, (jint)group_id, inputCodecConfigObj, outputCodecConfigObj); } void OnAudioGroupSelectableCodecConf( int group_id, std::vector<btle_audio_codec_config_t> input_selectable_codec_conf, std::vector<btle_audio_codec_config_t> output_selectable_codec_conf) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; jobject inputSelectableCodecConfigArray = prepareArrayOfCodecConfigs( sCallbackEnv.get(), input_selectable_codec_conf); jobject outputSelectableCodecConfigArray = prepareArrayOfCodecConfigs( sCallbackEnv.get(), output_selectable_codec_conf); sCallbackEnv->CallVoidMethod( mCallbacksObj, method_onAudioGroupCodecConf, (jint)group_id, inputCodecConfigObj, outputCodecConfigObj, mCallbacksObj, method_onAudioGroupSelectableCodecConf, (jint)group_id, inputSelectableCodecConfigArray, outputSelectableCodecConfigArray); } Loading Loading @@ -540,15 +575,85 @@ static void setCodecConfigPreferenceNative(JNIEnv* env, jobject /* object */, inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType); jint inputSampleRate = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getSampleRate); jint inputBitsPerSample = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getBitsPerSample); jint inputChannelCount = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getChannelCount); jint inputFrameDuration = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getFrameDuration); jint inputOctetsPerFrame = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getOctetsPerFrame); jint inputCodecPriority = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecPriority); btle_audio_codec_config_t input_codec_config = { .codec_type = static_cast<btle_audio_codec_index_t>(inputCodecType)}; .codec_type = static_cast<btle_audio_codec_index_t>(inputCodecType), .sample_rate = static_cast<btle_audio_sample_rate_index_t>(inputSampleRate), .bits_per_sample = static_cast<btle_audio_bits_per_sample_index_t>(inputBitsPerSample), .channel_count = static_cast<btle_audio_channel_count_index_t>(inputChannelCount), .frame_duration = static_cast<btle_audio_frame_duration_index_t>(inputFrameDuration), .octets_per_frame = static_cast<uint16_t>(inputOctetsPerFrame), .codec_priority = static_cast<int32_t>(inputCodecPriority), }; jint outputCodecType = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType); jint outputSampleRate = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getSampleRate); jint outputBitsPerSample = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getBitsPerSample); jint outputChannelCount = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getChannelCount); jint outputFrameDuration = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getFrameDuration); jint outputOctetsPerFrame = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getOctetsPerFrame); jint outputCodecPriority = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecPriority); btle_audio_codec_config_t output_codec_config = { .codec_type = static_cast<btle_audio_codec_index_t>(outputCodecType)}; .codec_type = static_cast<btle_audio_codec_index_t>(outputCodecType), .sample_rate = static_cast<btle_audio_sample_rate_index_t>(outputSampleRate), .bits_per_sample = static_cast<btle_audio_bits_per_sample_index_t>(outputBitsPerSample), .channel_count = static_cast<btle_audio_channel_count_index_t>(outputChannelCount), .frame_duration = static_cast<btle_audio_frame_duration_index_t>(outputFrameDuration), .octets_per_frame = static_cast<uint16_t>(outputOctetsPerFrame), .codec_priority = static_cast<int32_t>(outputCodecPriority), }; sLeAudioClientInterface->SetCodecConfigPreference( group_id, input_codec_config, output_codec_config); Loading Loading @@ -1465,12 +1570,14 @@ int register_com_android_bluetooth_le_audio(JNIEnv* env) { "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "[Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", &method_onAudioLocalCodecCapabilities}, {"onAudioGroupCodecConf", {"onAudioGroupCurrentCodecConf", "(ILandroid/bluetooth/BluetoothLeAudioCodecConfig;" "Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "[Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", &method_onAudioGroupCurrentCodecConf}, {"onAudioGroupSelectableCodecConf", "(I[Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "[Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", &method_onAudioGroupCodecConf}, &method_onAudioGroupSelectableCodecConf}, {"onHealthBasedRecommendationAction", "([BI)V", &method_onHealthBasedRecommendationAction}, {"onHealthBasedGroupRecommendationAction", "(II)V", Loading @@ -1484,6 +1591,18 @@ int register_com_android_bluetooth_le_audio(JNIEnv* env) { &android_bluetooth_BluetoothLeAudioCodecConfig.constructor}, {"getCodecType", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType}, {"getSampleRate", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getSampleRate}, {"getBitsPerSample", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getBitsPerSample}, {"getChannelCount", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getChannelCount}, {"getFrameDuration", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getFrameDuration}, {"getOctetsPerFrame", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getOctetsPerFrame}, {"getCodecPriority", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getCodecPriority}, }; GET_JAVA_METHODS(env, "android/bluetooth/BluetoothLeAudioCodecConfig", javaLeAudioCodecMethods); Loading android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java +23 −6 Original line number Diff line number Diff line Loading @@ -195,22 +195,39 @@ public class LeAudioNativeInterface { } @VisibleForTesting void onAudioGroupCodecConf(int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig, BluetoothLeAudioCodecConfig [] inputSelectableCodecConfig, BluetoothLeAudioCodecConfig [] outputSelectableCodecConfig) { void onAudioGroupCurrentCodecConf( int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig) { LeAudioStackEvent event = new LeAudioStackEvent( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED); LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED); event.valueInt1 = groupId; event.valueCodec1 = inputCodecConfig; event.valueCodec2 = outputCodecConfig; if (DBG) { Log.d(TAG, "onAudioGroupCurrentCodecConf: " + event); } sendMessageToService(event); } @VisibleForTesting void onAudioGroupSelectableCodecConf( int groupId, BluetoothLeAudioCodecConfig[] inputSelectableCodecConfig, BluetoothLeAudioCodecConfig[] outputSelectableCodecConfig) { LeAudioStackEvent event = new LeAudioStackEvent( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED); event.valueInt1 = groupId; event.valueCodecList1 = Arrays.asList(inputSelectableCodecConfig); event.valueCodecList2 = Arrays.asList(outputSelectableCodecConfig); if (DBG) { Log.d(TAG, "onAudioGroupCodecConf: " + event); Log.d(TAG, "onAudioGroupSelectableCodecConf: " + event); } sendMessageToService(event); } Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +23 −5 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ public class LeAudioService extends ProfileService { mCurrentLeadDevice = null; mInbandRingtoneEnabled = isInbandRingtonEnabled; mAvailableContexts = 0; mInputSelectableConfig = new ArrayList<>(); mOutputSelectableConfig = new ArrayList<>(); } public Boolean mIsConnected; Loading @@ -196,6 +198,8 @@ public class LeAudioService extends ProfileService { BluetoothDevice mCurrentLeadDevice; Boolean mInbandRingtoneEnabled; Integer mAvailableContexts; List<BluetoothLeAudioCodecConfig> mInputSelectableConfig; List<BluetoothLeAudioCodecConfig> mOutputSelectableConfig; } private static class LeAudioDeviceDescriptor { Loading Loading @@ -2173,7 +2177,19 @@ public class LeAudioService extends ProfileService { mInputLocalCodecCapabilities = stackEvent.valueCodecList1; mOutputLocalCodecCapabilities = stackEvent.valueCodecList2; } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED) { == LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED) { int groupId = stackEvent.valueInt1; LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null) { Log.e(TAG, " Group not found " + groupId); return; } descriptor.mInputSelectableConfig = stackEvent.valueCodecList1; descriptor.mOutputSelectableConfig = stackEvent.valueCodecList2; } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED) { int groupId = stackEvent.valueInt1; LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null) { Loading @@ -2182,11 +2198,13 @@ public class LeAudioService extends ProfileService { } BluetoothLeAudioCodecStatus status = new BluetoothLeAudioCodecStatus(stackEvent.valueCodec1, stackEvent.valueCodec2, mInputLocalCodecCapabilities, new BluetoothLeAudioCodecStatus( stackEvent.valueCodec1, stackEvent.valueCodec2, mInputLocalCodecCapabilities, mOutputLocalCodecCapabilities, stackEvent.valueCodecList1, stackEvent.valueCodecList2); descriptor.mInputSelectableConfig, descriptor.mOutputSelectableConfig); if (DBG) { if (descriptor.mCodecStatus != null) { Loading android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java +63 −30 Original line number Diff line number Diff line Loading @@ -35,12 +35,13 @@ public class LeAudioStackEvent { public static final int EVENT_TYPE_AUDIO_CONF_CHANGED = 4; public static final int EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE = 5; public static final int EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED = 6; public static final int EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED = 7; public static final int EVENT_TYPE_NATIVE_INITIALIZED = 8; public static final int EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION = 9; public static final int EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION = 10; public static final int EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED = 7; public static final int EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED = 8; public static final int EVENT_TYPE_NATIVE_INITIALIZED = 9; public static final int EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION = 10; public static final int EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION = 11; // -------- DO NOT PUT ANY NEW UNICAST EVENTS BELOW THIS LINE------------- public static final int EVENT_TYPE_UNICAST_MAX = 11; public static final int EVENT_TYPE_UNICAST_MAX = 12; // Broadcast related events public static final int EVENT_TYPE_BROADCAST_CREATED = EVENT_TYPE_UNICAST_MAX + 1; Loading Loading @@ -99,18 +100,33 @@ public class LeAudioStackEvent { StringBuilder result = new StringBuilder(); result.append("LeAudioStackEvent {type:" + eventTypeToString(type)); result.append(", device:" + device); if (type != EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED) { result.append(", value1:" + eventTypeValue1ToString(type, valueInt1)); result.append(", value2:" + eventTypeValue2ToString(type, valueInt2)); result.append(", value3:" + eventTypeValue3ToString(type, valueInt3)); result.append(", value4:" + eventTypeValue4ToString(type, valueInt4)); result.append(", value5:" + eventTypeValue5ToString(type, valueInt5)); result.append(", valueBool1:" + eventTypeValueBool1ToString(type, valueBool1)); } else { result.append( ", valueCodecList1:" + eventTypeValueCodecList1ToString(type, valueCodecList1)); result.append( ", valueCodecList2:" + eventTypeValueCodecList2ToString(type, valueCodecList2)); } if (type == EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED) { result.append(", valueCodec1:" + eventTypeValueCodec1ToString(type, valueCodec1)); result.append(", valueCodec2:" + eventTypeValueCodec2ToString(type, valueCodec2)); result.append(", valueCodecList1:" + eventTypeValueCodecList1ToString(type, valueCodecList1)); result.append(", valueCodecList2:" + eventTypeValueCodecList2ToString(type, valueCodecList2)); } if (type == EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED) { result.append( ", valueCodecList1:" + eventTypeValueCodecList1ToString(type, valueCodecList1)); result.append( ", valueCodecList2:" + eventTypeValueCodecList2ToString(type, valueCodecList2)); } if (type == EVENT_TYPE_BROADCAST_METADATA_CHANGED) { result.append(", broadcastMetadata:" + eventTypeValueBroadcastMetadataToString(broadcastMetadata)); Loading Loading @@ -143,8 +159,10 @@ public class LeAudioStackEvent { return "EVENT_TYPE_BROADCAST_METADATA_CHANGED"; case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: return "EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED"; case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: return "EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED"; case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED"; case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: return "EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED"; case EVENT_TYPE_NATIVE_INITIALIZED: return "EVENT_TYPE_NATIVE_INITIALIZED"; case EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION: Loading Loading @@ -173,7 +191,8 @@ public class LeAudioStackEvent { } case EVENT_TYPE_GROUP_NODE_STATUS_CHANGED: // same as EVENT_TYPE_GROUP_STATUS_CHANGED case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: // same as EVENT_TYPE_GROUP_STATUS_CHANGED case EVENT_TYPE_GROUP_STATUS_CHANGED: return "{group_id:" + Integer.toString(value) + "}"; Loading Loading @@ -293,7 +312,7 @@ public class LeAudioStackEvent { private static String eventTypeValueCodec1ToString(int type, BluetoothLeAudioCodecConfig value) { switch (type) { case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "{input codec =" + value + "}"; default: return "<unused>"; Loading @@ -303,7 +322,7 @@ public class LeAudioStackEvent { private static String eventTypeValueCodec2ToString(int type, BluetoothLeAudioCodecConfig value) { switch (type) { case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "{output codec =" + value + "}"; default: return "<unused>"; Loading @@ -312,11 +331,18 @@ public class LeAudioStackEvent { private static String eventTypeValueCodecList1ToString(int type, List<BluetoothLeAudioCodecConfig> value) { String valueStr = ""; switch (type) { case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: return "{input local capa codec = " + value + "}"; case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: return "{input selectable codec = " + value + "}"; for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{input local capa codec = \n" + valueStr + "}"; case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{input selectable codec =" + valueStr + "}"; default: return "<unused>"; } Loading @@ -324,11 +350,18 @@ public class LeAudioStackEvent { private static String eventTypeValueCodecList2ToString(int type, List<BluetoothLeAudioCodecConfig> value) { String valueStr = ""; switch (type) { case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: return "{output local capa codec = " + value + "}"; case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: return "{output selectable codec = " + value + "}"; for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{output local capa codec = \n" + valueStr + "}"; case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{output selectable codec =" + valueStr + "}"; default: return "<unused>"; } Loading android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java +21 −5 Original line number Diff line number Diff line Loading @@ -135,7 +135,22 @@ public class LeAudioNativeInterfaceTest { } @Test public void onAudioGroupCodecConf() { public void onAudioGroupCurrentCodecConf() { int groupId = 1; BluetoothLeAudioCodecConfig inputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); BluetoothLeAudioCodecConfig outputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); mNativeInterface.onAudioGroupCurrentCodecConf(groupId, inputConfig, outputConfig); ArgumentCaptor<LeAudioStackEvent> event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); assertThat(event.getValue().type) .isEqualTo(LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED); } @Test public void onAudioGroupSelectableCodecConf() { int groupId = 1; BluetoothLeAudioCodecConfig inputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); Loading @@ -146,13 +161,14 @@ public class LeAudioNativeInterfaceTest { BluetoothLeAudioCodecConfig[] outputSelectableCodecConfig = new BluetoothLeAudioCodecConfig[] { outputConfig }; mNativeInterface.onAudioGroupCodecConf(groupId, inputConfig, outputConfig, inputSelectableCodecConfig, outputSelectableCodecConfig); mNativeInterface.onAudioGroupSelectableCodecConf( groupId, inputSelectableCodecConfig, outputSelectableCodecConfig); ArgumentCaptor<LeAudioStackEvent> event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); assertThat(event.getValue().type).isEqualTo( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED); assertThat(event.getValue().type) .isEqualTo( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED); } } Loading
android/app/jni/com_android_bluetooth_le_audio.cpp +138 −19 Original line number Diff line number Diff line Loading @@ -27,8 +27,12 @@ using bluetooth::le_audio::BroadcastId; using bluetooth::le_audio::BroadcastState; using bluetooth::le_audio::btle_audio_bits_per_sample_index_t; using bluetooth::le_audio::btle_audio_channel_count_index_t; using bluetooth::le_audio::btle_audio_codec_config_t; using bluetooth::le_audio::btle_audio_codec_index_t; using bluetooth::le_audio::btle_audio_frame_duration_index_t; using bluetooth::le_audio::btle_audio_sample_rate_index_t; using bluetooth::le_audio::ConnectionState; using bluetooth::le_audio::GroupNodeStatus; using bluetooth::le_audio::GroupStatus; Loading @@ -45,7 +49,8 @@ static jmethodID method_onGroupNodeStatus; static jmethodID method_onAudioConf; static jmethodID method_onSinkAudioLocationAvailable; static jmethodID method_onAudioLocalCodecCapabilities; static jmethodID method_onAudioGroupCodecConf; static jmethodID method_onAudioGroupCurrentCodecConf; static jmethodID method_onAudioGroupSelectableCodecConf; static jmethodID method_onHealthBasedRecommendationAction; static jmethodID method_onHealthBasedGroupRecommendationAction; Loading @@ -53,6 +58,12 @@ static struct { jclass clazz; jmethodID constructor; jmethodID getCodecType; jmethodID getSampleRate; jmethodID getBitsPerSample; jmethodID getChannelCount; jmethodID getFrameDuration; jmethodID getOctetsPerFrame; jmethodID getCodecPriority; } android_bluetooth_BluetoothLeAudioCodecConfig; static struct { Loading Loading @@ -99,10 +110,21 @@ static std::shared_timed_mutex callbacks_mutex; jobject prepareCodecConfigObj(JNIEnv* env, btle_audio_codec_config_t codecConfig) { jobject codecConfigObj = env->NewObject(android_bluetooth_BluetoothLeAudioCodecConfig.clazz, LOG(INFO) << __func__ << "ct: " << codecConfig.codec_type << ", codec_priority: " << codecConfig.codec_priority << ", sample_rate: " << codecConfig.sample_rate << ", bits_per_sample: " << codecConfig.bits_per_sample << ", channel_count: " << codecConfig.channel_count << ", frame_duration: " << codecConfig.frame_duration << ", octets_per_frame: " << codecConfig.octets_per_frame; jobject codecConfigObj = env->NewObject( android_bluetooth_BluetoothLeAudioCodecConfig.clazz, android_bluetooth_BluetoothLeAudioCodecConfig.constructor, (jint)codecConfig.codec_type, 0, 0, 0, 0, 0, 0, 0, 0); (jint)codecConfig.codec_type, (jint)codecConfig.codec_priority, (jint)codecConfig.sample_rate, (jint)codecConfig.bits_per_sample, (jint)codecConfig.channel_count, (jint)codecConfig.frame_duration, (jint)codecConfig.octets_per_frame, 0, 0); return codecConfigObj; } Loading Loading @@ -247,12 +269,9 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { localInputCapCodecConfigArray, localOutputCapCodecConfigArray); } void OnAudioGroupCodecConf( void OnAudioGroupCurrentCodecConf( int group_id, btle_audio_codec_config_t input_codec_conf, btle_audio_codec_config_t /* output_codec_conf */, std::vector<btle_audio_codec_config_t> input_selectable_codec_conf, std::vector<btle_audio_codec_config_t> output_selectable_codec_conf) override { btle_audio_codec_config_t output_codec_conf) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); Loading @@ -262,15 +281,31 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { jobject inputCodecConfigObj = prepareCodecConfigObj(sCallbackEnv.get(), input_codec_conf); jobject outputCodecConfigObj = prepareCodecConfigObj(sCallbackEnv.get(), input_codec_conf); prepareCodecConfigObj(sCallbackEnv.get(), output_codec_conf); sCallbackEnv->CallVoidMethod( mCallbacksObj, method_onAudioGroupCurrentCodecConf, (jint)group_id, inputCodecConfigObj, outputCodecConfigObj); } void OnAudioGroupSelectableCodecConf( int group_id, std::vector<btle_audio_codec_config_t> input_selectable_codec_conf, std::vector<btle_audio_codec_config_t> output_selectable_codec_conf) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; jobject inputSelectableCodecConfigArray = prepareArrayOfCodecConfigs( sCallbackEnv.get(), input_selectable_codec_conf); jobject outputSelectableCodecConfigArray = prepareArrayOfCodecConfigs( sCallbackEnv.get(), output_selectable_codec_conf); sCallbackEnv->CallVoidMethod( mCallbacksObj, method_onAudioGroupCodecConf, (jint)group_id, inputCodecConfigObj, outputCodecConfigObj, mCallbacksObj, method_onAudioGroupSelectableCodecConf, (jint)group_id, inputSelectableCodecConfigArray, outputSelectableCodecConfigArray); } Loading Loading @@ -540,15 +575,85 @@ static void setCodecConfigPreferenceNative(JNIEnv* env, jobject /* object */, inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType); jint inputSampleRate = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getSampleRate); jint inputBitsPerSample = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getBitsPerSample); jint inputChannelCount = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getChannelCount); jint inputFrameDuration = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getFrameDuration); jint inputOctetsPerFrame = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getOctetsPerFrame); jint inputCodecPriority = env->CallIntMethod( inputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecPriority); btle_audio_codec_config_t input_codec_config = { .codec_type = static_cast<btle_audio_codec_index_t>(inputCodecType)}; .codec_type = static_cast<btle_audio_codec_index_t>(inputCodecType), .sample_rate = static_cast<btle_audio_sample_rate_index_t>(inputSampleRate), .bits_per_sample = static_cast<btle_audio_bits_per_sample_index_t>(inputBitsPerSample), .channel_count = static_cast<btle_audio_channel_count_index_t>(inputChannelCount), .frame_duration = static_cast<btle_audio_frame_duration_index_t>(inputFrameDuration), .octets_per_frame = static_cast<uint16_t>(inputOctetsPerFrame), .codec_priority = static_cast<int32_t>(inputCodecPriority), }; jint outputCodecType = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType); jint outputSampleRate = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getSampleRate); jint outputBitsPerSample = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getBitsPerSample); jint outputChannelCount = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getChannelCount); jint outputFrameDuration = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getFrameDuration); jint outputOctetsPerFrame = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getOctetsPerFrame); jint outputCodecPriority = env->CallIntMethod( outputCodecConfig, android_bluetooth_BluetoothLeAudioCodecConfig.getCodecPriority); btle_audio_codec_config_t output_codec_config = { .codec_type = static_cast<btle_audio_codec_index_t>(outputCodecType)}; .codec_type = static_cast<btle_audio_codec_index_t>(outputCodecType), .sample_rate = static_cast<btle_audio_sample_rate_index_t>(outputSampleRate), .bits_per_sample = static_cast<btle_audio_bits_per_sample_index_t>(outputBitsPerSample), .channel_count = static_cast<btle_audio_channel_count_index_t>(outputChannelCount), .frame_duration = static_cast<btle_audio_frame_duration_index_t>(outputFrameDuration), .octets_per_frame = static_cast<uint16_t>(outputOctetsPerFrame), .codec_priority = static_cast<int32_t>(outputCodecPriority), }; sLeAudioClientInterface->SetCodecConfigPreference( group_id, input_codec_config, output_codec_config); Loading Loading @@ -1465,12 +1570,14 @@ int register_com_android_bluetooth_le_audio(JNIEnv* env) { "([Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "[Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", &method_onAudioLocalCodecCapabilities}, {"onAudioGroupCodecConf", {"onAudioGroupCurrentCodecConf", "(ILandroid/bluetooth/BluetoothLeAudioCodecConfig;" "Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "[Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", &method_onAudioGroupCurrentCodecConf}, {"onAudioGroupSelectableCodecConf", "(I[Landroid/bluetooth/BluetoothLeAudioCodecConfig;" "[Landroid/bluetooth/BluetoothLeAudioCodecConfig;)V", &method_onAudioGroupCodecConf}, &method_onAudioGroupSelectableCodecConf}, {"onHealthBasedRecommendationAction", "([BI)V", &method_onHealthBasedRecommendationAction}, {"onHealthBasedGroupRecommendationAction", "(II)V", Loading @@ -1484,6 +1591,18 @@ int register_com_android_bluetooth_le_audio(JNIEnv* env) { &android_bluetooth_BluetoothLeAudioCodecConfig.constructor}, {"getCodecType", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getCodecType}, {"getSampleRate", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getSampleRate}, {"getBitsPerSample", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getBitsPerSample}, {"getChannelCount", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getChannelCount}, {"getFrameDuration", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getFrameDuration}, {"getOctetsPerFrame", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getOctetsPerFrame}, {"getCodecPriority", "()I", &android_bluetooth_BluetoothLeAudioCodecConfig.getCodecPriority}, }; GET_JAVA_METHODS(env, "android/bluetooth/BluetoothLeAudioCodecConfig", javaLeAudioCodecMethods); Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java +23 −6 Original line number Diff line number Diff line Loading @@ -195,22 +195,39 @@ public class LeAudioNativeInterface { } @VisibleForTesting void onAudioGroupCodecConf(int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig, BluetoothLeAudioCodecConfig [] inputSelectableCodecConfig, BluetoothLeAudioCodecConfig [] outputSelectableCodecConfig) { void onAudioGroupCurrentCodecConf( int groupId, BluetoothLeAudioCodecConfig inputCodecConfig, BluetoothLeAudioCodecConfig outputCodecConfig) { LeAudioStackEvent event = new LeAudioStackEvent( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED); LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED); event.valueInt1 = groupId; event.valueCodec1 = inputCodecConfig; event.valueCodec2 = outputCodecConfig; if (DBG) { Log.d(TAG, "onAudioGroupCurrentCodecConf: " + event); } sendMessageToService(event); } @VisibleForTesting void onAudioGroupSelectableCodecConf( int groupId, BluetoothLeAudioCodecConfig[] inputSelectableCodecConfig, BluetoothLeAudioCodecConfig[] outputSelectableCodecConfig) { LeAudioStackEvent event = new LeAudioStackEvent( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED); event.valueInt1 = groupId; event.valueCodecList1 = Arrays.asList(inputSelectableCodecConfig); event.valueCodecList2 = Arrays.asList(outputSelectableCodecConfig); if (DBG) { Log.d(TAG, "onAudioGroupCodecConf: " + event); Log.d(TAG, "onAudioGroupSelectableCodecConf: " + event); } sendMessageToService(event); } Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +23 −5 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ public class LeAudioService extends ProfileService { mCurrentLeadDevice = null; mInbandRingtoneEnabled = isInbandRingtonEnabled; mAvailableContexts = 0; mInputSelectableConfig = new ArrayList<>(); mOutputSelectableConfig = new ArrayList<>(); } public Boolean mIsConnected; Loading @@ -196,6 +198,8 @@ public class LeAudioService extends ProfileService { BluetoothDevice mCurrentLeadDevice; Boolean mInbandRingtoneEnabled; Integer mAvailableContexts; List<BluetoothLeAudioCodecConfig> mInputSelectableConfig; List<BluetoothLeAudioCodecConfig> mOutputSelectableConfig; } private static class LeAudioDeviceDescriptor { Loading Loading @@ -2173,7 +2177,19 @@ public class LeAudioService extends ProfileService { mInputLocalCodecCapabilities = stackEvent.valueCodecList1; mOutputLocalCodecCapabilities = stackEvent.valueCodecList2; } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED) { == LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED) { int groupId = stackEvent.valueInt1; LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null) { Log.e(TAG, " Group not found " + groupId); return; } descriptor.mInputSelectableConfig = stackEvent.valueCodecList1; descriptor.mOutputSelectableConfig = stackEvent.valueCodecList2; } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED) { int groupId = stackEvent.valueInt1; LeAudioGroupDescriptor descriptor = getGroupDescriptor(groupId); if (descriptor == null) { Loading @@ -2182,11 +2198,13 @@ public class LeAudioService extends ProfileService { } BluetoothLeAudioCodecStatus status = new BluetoothLeAudioCodecStatus(stackEvent.valueCodec1, stackEvent.valueCodec2, mInputLocalCodecCapabilities, new BluetoothLeAudioCodecStatus( stackEvent.valueCodec1, stackEvent.valueCodec2, mInputLocalCodecCapabilities, mOutputLocalCodecCapabilities, stackEvent.valueCodecList1, stackEvent.valueCodecList2); descriptor.mInputSelectableConfig, descriptor.mOutputSelectableConfig); if (DBG) { if (descriptor.mCodecStatus != null) { Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java +63 −30 Original line number Diff line number Diff line Loading @@ -35,12 +35,13 @@ public class LeAudioStackEvent { public static final int EVENT_TYPE_AUDIO_CONF_CHANGED = 4; public static final int EVENT_TYPE_SINK_AUDIO_LOCATION_AVAILABLE = 5; public static final int EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED = 6; public static final int EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED = 7; public static final int EVENT_TYPE_NATIVE_INITIALIZED = 8; public static final int EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION = 9; public static final int EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION = 10; public static final int EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED = 7; public static final int EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED = 8; public static final int EVENT_TYPE_NATIVE_INITIALIZED = 9; public static final int EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION = 10; public static final int EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION = 11; // -------- DO NOT PUT ANY NEW UNICAST EVENTS BELOW THIS LINE------------- public static final int EVENT_TYPE_UNICAST_MAX = 11; public static final int EVENT_TYPE_UNICAST_MAX = 12; // Broadcast related events public static final int EVENT_TYPE_BROADCAST_CREATED = EVENT_TYPE_UNICAST_MAX + 1; Loading Loading @@ -99,18 +100,33 @@ public class LeAudioStackEvent { StringBuilder result = new StringBuilder(); result.append("LeAudioStackEvent {type:" + eventTypeToString(type)); result.append(", device:" + device); if (type != EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED) { result.append(", value1:" + eventTypeValue1ToString(type, valueInt1)); result.append(", value2:" + eventTypeValue2ToString(type, valueInt2)); result.append(", value3:" + eventTypeValue3ToString(type, valueInt3)); result.append(", value4:" + eventTypeValue4ToString(type, valueInt4)); result.append(", value5:" + eventTypeValue5ToString(type, valueInt5)); result.append(", valueBool1:" + eventTypeValueBool1ToString(type, valueBool1)); } else { result.append( ", valueCodecList1:" + eventTypeValueCodecList1ToString(type, valueCodecList1)); result.append( ", valueCodecList2:" + eventTypeValueCodecList2ToString(type, valueCodecList2)); } if (type == EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED) { result.append(", valueCodec1:" + eventTypeValueCodec1ToString(type, valueCodec1)); result.append(", valueCodec2:" + eventTypeValueCodec2ToString(type, valueCodec2)); result.append(", valueCodecList1:" + eventTypeValueCodecList1ToString(type, valueCodecList1)); result.append(", valueCodecList2:" + eventTypeValueCodecList2ToString(type, valueCodecList2)); } if (type == EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED) { result.append( ", valueCodecList1:" + eventTypeValueCodecList1ToString(type, valueCodecList1)); result.append( ", valueCodecList2:" + eventTypeValueCodecList2ToString(type, valueCodecList2)); } if (type == EVENT_TYPE_BROADCAST_METADATA_CHANGED) { result.append(", broadcastMetadata:" + eventTypeValueBroadcastMetadataToString(broadcastMetadata)); Loading Loading @@ -143,8 +159,10 @@ public class LeAudioStackEvent { return "EVENT_TYPE_BROADCAST_METADATA_CHANGED"; case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: return "EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED"; case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: return "EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED"; case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED"; case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: return "EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED"; case EVENT_TYPE_NATIVE_INITIALIZED: return "EVENT_TYPE_NATIVE_INITIALIZED"; case EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION: Loading Loading @@ -173,7 +191,8 @@ public class LeAudioStackEvent { } case EVENT_TYPE_GROUP_NODE_STATUS_CHANGED: // same as EVENT_TYPE_GROUP_STATUS_CHANGED case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: // same as EVENT_TYPE_GROUP_STATUS_CHANGED case EVENT_TYPE_GROUP_STATUS_CHANGED: return "{group_id:" + Integer.toString(value) + "}"; Loading Loading @@ -293,7 +312,7 @@ public class LeAudioStackEvent { private static String eventTypeValueCodec1ToString(int type, BluetoothLeAudioCodecConfig value) { switch (type) { case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "{input codec =" + value + "}"; default: return "<unused>"; Loading @@ -303,7 +322,7 @@ public class LeAudioStackEvent { private static String eventTypeValueCodec2ToString(int type, BluetoothLeAudioCodecConfig value) { switch (type) { case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: case EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED: return "{output codec =" + value + "}"; default: return "<unused>"; Loading @@ -312,11 +331,18 @@ public class LeAudioStackEvent { private static String eventTypeValueCodecList1ToString(int type, List<BluetoothLeAudioCodecConfig> value) { String valueStr = ""; switch (type) { case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: return "{input local capa codec = " + value + "}"; case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: return "{input selectable codec = " + value + "}"; for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{input local capa codec = \n" + valueStr + "}"; case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{input selectable codec =" + valueStr + "}"; default: return "<unused>"; } Loading @@ -324,11 +350,18 @@ public class LeAudioStackEvent { private static String eventTypeValueCodecList2ToString(int type, List<BluetoothLeAudioCodecConfig> value) { String valueStr = ""; switch (type) { case EVENT_TYPE_AUDIO_LOCAL_CODEC_CONFIG_CAPA_CHANGED: return "{output local capa codec = " + value + "}"; case EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED: return "{output selectable codec = " + value + "}"; for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{output local capa codec = \n" + valueStr + "}"; case EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED: for (BluetoothLeAudioCodecConfig n : value) { valueStr = valueStr.concat(n.toString() + "\n"); } return "{output selectable codec =" + valueStr + "}"; default: return "<unused>"; } Loading
android/app/tests/unit/src/com/android/bluetooth/le_audio/LeAudioNativeInterfaceTest.java +21 −5 Original line number Diff line number Diff line Loading @@ -135,7 +135,22 @@ public class LeAudioNativeInterfaceTest { } @Test public void onAudioGroupCodecConf() { public void onAudioGroupCurrentCodecConf() { int groupId = 1; BluetoothLeAudioCodecConfig inputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); BluetoothLeAudioCodecConfig outputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); mNativeInterface.onAudioGroupCurrentCodecConf(groupId, inputConfig, outputConfig); ArgumentCaptor<LeAudioStackEvent> event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); assertThat(event.getValue().type) .isEqualTo(LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED); } @Test public void onAudioGroupSelectableCodecConf() { int groupId = 1; BluetoothLeAudioCodecConfig inputConfig = new BluetoothLeAudioCodecConfig.Builder().build(); Loading @@ -146,13 +161,14 @@ public class LeAudioNativeInterfaceTest { BluetoothLeAudioCodecConfig[] outputSelectableCodecConfig = new BluetoothLeAudioCodecConfig[] { outputConfig }; mNativeInterface.onAudioGroupCodecConf(groupId, inputConfig, outputConfig, inputSelectableCodecConfig, outputSelectableCodecConfig); mNativeInterface.onAudioGroupSelectableCodecConf( groupId, inputSelectableCodecConfig, outputSelectableCodecConfig); ArgumentCaptor<LeAudioStackEvent> event = ArgumentCaptor.forClass(LeAudioStackEvent.class); verify(mMockService).messageFromNative(event.capture()); assertThat(event.getValue().type).isEqualTo( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CODEC_CONFIG_CHANGED); assertThat(event.getValue().type) .isEqualTo( LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_SELECTABLE_CODEC_CONFIG_CHANGED); } }