Loading android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -31,4 +31,5 @@ oneway interface IBluetoothLeAudioCallback { void onGroupNodeAdded(in BluetoothDevice device, int groupId); void onGroupNodeRemoved(in BluetoothDevice device, int groupId); void onGroupStatusChanged(int groupId, int groupStatus); void onGroupStreamStatusChanged(int groupId, int groupStreamStatus); } android/app/jni/com_android_bluetooth_le_audio.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ 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; using bluetooth::le_audio::GroupStreamStatus; using bluetooth::le_audio::LeAudioBroadcasterCallbacks; using bluetooth::le_audio::LeAudioBroadcasterInterface; using bluetooth::le_audio::LeAudioClientCallbacks; Loading @@ -55,6 +56,7 @@ static jmethodID method_onAudioGroupSelectableCodecConf; static jmethodID method_onHealthBasedRecommendationAction; static jmethodID method_onHealthBasedGroupRecommendationAction; static jmethodID method_onUnicastMonitorModeStatus; static jmethodID method_onGroupStreamStatus; static struct { jclass clazz; Loading Loading @@ -360,6 +362,18 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { method_onUnicastMonitorModeStatus, (jint)direction, (jint)status); } void OnGroupStreamStatus(int group_id, GroupStreamStatus group_stream_status) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGroupStreamStatus, (jint)group_id, (jint)group_stream_status); } }; static LeAudioClientCallbacksImpl sLeAudioClientCallbacks; Loading Loading @@ -1611,6 +1625,7 @@ int register_com_android_bluetooth_le_audio(JNIEnv* env) { &method_onHealthBasedGroupRecommendationAction}, {"onUnicastMonitorModeStatus", "(II)V", &method_onUnicastMonitorModeStatus}, {"onGroupStreamStatus", "(II)V", &method_onGroupStreamStatus}, }; GET_JAVA_METHODS(env, "com/android/bluetooth/le_audio/LeAudioNativeInterface", javaMethods); Loading android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java +13 −0 Original line number Diff line number Diff line Loading @@ -272,6 +272,19 @@ public class LeAudioNativeInterface { sendMessageToService(event); } @VisibleForTesting void onGroupStreamStatus(int groupId, int groupStreamStatus) { LeAudioStackEvent event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED); event.valueInt1 = groupId; event.valueInt2 = groupStreamStatus; if (DBG) { Log.d(TAG, "onGroupStreamStatus: " + event); } sendMessageToService(event); } /** * Initializes the native interface. * Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +18 −0 Original line number Diff line number Diff line Loading @@ -2165,6 +2165,22 @@ public class LeAudioService extends ProfileService { } } private void notifyGroupStreamStatusChanged(int groupId, int groupStreamStatus) { if (mLeAudioCallbacks != null) { int n = mLeAudioCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { mLeAudioCallbacks .getBroadcastItem(i) .onGroupStreamStatusChanged(groupId, groupStreamStatus); } catch (RemoteException e) { continue; } } mLeAudioCallbacks.finishBroadcast(); } } @VisibleForTesting void handleGroupIdleDuringCall() { if (mHfpHandoverDevice == null) { Loading Loading @@ -2779,6 +2795,8 @@ public class LeAudioService extends ProfileService { } } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS) { handleUnicastStreamStatusChange(stackEvent.valueInt1, stackEvent.valueInt2); } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED) { notifyGroupStreamStatusChanged(stackEvent.valueInt1, stackEvent.valueInt2); } } Loading android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java +18 −1 Original line number Diff line number Diff line Loading @@ -42,8 +42,9 @@ public class LeAudioStackEvent { public static final int EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION = 10; public static final int EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION = 11; public static final int EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS = 12; public static final int EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED = 13; // -------- DO NOT PUT ANY NEW UNICAST EVENTS BELOW THIS LINE------------- public static final int EVENT_TYPE_UNICAST_MAX = 13; public static final int EVENT_TYPE_UNICAST_MAX = 14; // Broadcast related events public static final int EVENT_TYPE_BROADCAST_CREATED = EVENT_TYPE_UNICAST_MAX + 1; Loading Loading @@ -90,6 +91,9 @@ public class LeAudioStackEvent { static final int DIRECTION_SINK = 1; static final int DIRECTION_SOURCE = 2; static final int GROUP_STREAM_STATUS_IDLE = 0; static final int GROUP_STREAM_STATUS_STREAMING = 1; public int type = EVENT_TYPE_NONE; public BluetoothDevice device; public int valueInt1 = 0; Loading Loading @@ -185,6 +189,8 @@ public class LeAudioStackEvent { return "EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION"; case EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS: return "EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS"; case EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED: return "EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED"; default: return "EVENT_TYPE_UNKNOWN:" + type; } Loading @@ -210,6 +216,8 @@ public class LeAudioStackEvent { 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_STREAM_STATUS_CHANGED: // same as EVENT_TYPE_GROUP_STATUS_CHANGED case EVENT_TYPE_GROUP_STATUS_CHANGED: return "{group_id:" + Integer.toString(value) + "}"; case EVENT_TYPE_AUDIO_CONF_CHANGED: Loading Loading @@ -300,6 +308,15 @@ public class LeAudioStackEvent { default: return "UNKNOWN"; } case EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED: switch (value) { case GROUP_STREAM_STATUS_IDLE: return "GROUP_STREAM_STATUS_IDLE"; case GROUP_STREAM_STATUS_STREAMING: return "GROUP_STREAM_STATUS_STREAMING"; default: return "UNKNOWN"; } default: break; } Loading Loading
android/app/aidl/android/bluetooth/IBluetoothLeAudioCallback.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -31,4 +31,5 @@ oneway interface IBluetoothLeAudioCallback { void onGroupNodeAdded(in BluetoothDevice device, int groupId); void onGroupNodeRemoved(in BluetoothDevice device, int groupId); void onGroupStatusChanged(int groupId, int groupStatus); void onGroupStreamStatusChanged(int groupId, int groupStreamStatus); }
android/app/jni/com_android_bluetooth_le_audio.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ 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; using bluetooth::le_audio::GroupStreamStatus; using bluetooth::le_audio::LeAudioBroadcasterCallbacks; using bluetooth::le_audio::LeAudioBroadcasterInterface; using bluetooth::le_audio::LeAudioClientCallbacks; Loading @@ -55,6 +56,7 @@ static jmethodID method_onAudioGroupSelectableCodecConf; static jmethodID method_onHealthBasedRecommendationAction; static jmethodID method_onHealthBasedGroupRecommendationAction; static jmethodID method_onUnicastMonitorModeStatus; static jmethodID method_onGroupStreamStatus; static struct { jclass clazz; Loading Loading @@ -360,6 +362,18 @@ class LeAudioClientCallbacksImpl : public LeAudioClientCallbacks { method_onUnicastMonitorModeStatus, (jint)direction, (jint)status); } void OnGroupStreamStatus(int group_id, GroupStreamStatus group_stream_status) override { LOG(INFO) << __func__; std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGroupStreamStatus, (jint)group_id, (jint)group_stream_status); } }; static LeAudioClientCallbacksImpl sLeAudioClientCallbacks; Loading Loading @@ -1611,6 +1625,7 @@ int register_com_android_bluetooth_le_audio(JNIEnv* env) { &method_onHealthBasedGroupRecommendationAction}, {"onUnicastMonitorModeStatus", "(II)V", &method_onUnicastMonitorModeStatus}, {"onGroupStreamStatus", "(II)V", &method_onGroupStreamStatus}, }; GET_JAVA_METHODS(env, "com/android/bluetooth/le_audio/LeAudioNativeInterface", javaMethods); Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioNativeInterface.java +13 −0 Original line number Diff line number Diff line Loading @@ -272,6 +272,19 @@ public class LeAudioNativeInterface { sendMessageToService(event); } @VisibleForTesting void onGroupStreamStatus(int groupId, int groupStreamStatus) { LeAudioStackEvent event = new LeAudioStackEvent(LeAudioStackEvent.EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED); event.valueInt1 = groupId; event.valueInt2 = groupStreamStatus; if (DBG) { Log.d(TAG, "onGroupStreamStatus: " + event); } sendMessageToService(event); } /** * Initializes the native interface. * Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +18 −0 Original line number Diff line number Diff line Loading @@ -2165,6 +2165,22 @@ public class LeAudioService extends ProfileService { } } private void notifyGroupStreamStatusChanged(int groupId, int groupStreamStatus) { if (mLeAudioCallbacks != null) { int n = mLeAudioCallbacks.beginBroadcast(); for (int i = 0; i < n; i++) { try { mLeAudioCallbacks .getBroadcastItem(i) .onGroupStreamStatusChanged(groupId, groupStreamStatus); } catch (RemoteException e) { continue; } } mLeAudioCallbacks.finishBroadcast(); } } @VisibleForTesting void handleGroupIdleDuringCall() { if (mHfpHandoverDevice == null) { Loading Loading @@ -2779,6 +2795,8 @@ public class LeAudioService extends ProfileService { } } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS) { handleUnicastStreamStatusChange(stackEvent.valueInt1, stackEvent.valueInt2); } else if (stackEvent.type == LeAudioStackEvent.EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED) { notifyGroupStreamStatusChanged(stackEvent.valueInt1, stackEvent.valueInt2); } } Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioStackEvent.java +18 −1 Original line number Diff line number Diff line Loading @@ -42,8 +42,9 @@ public class LeAudioStackEvent { public static final int EVENT_TYPE_HEALTH_BASED_DEV_RECOMMENDATION = 10; public static final int EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION = 11; public static final int EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS = 12; public static final int EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED = 13; // -------- DO NOT PUT ANY NEW UNICAST EVENTS BELOW THIS LINE------------- public static final int EVENT_TYPE_UNICAST_MAX = 13; public static final int EVENT_TYPE_UNICAST_MAX = 14; // Broadcast related events public static final int EVENT_TYPE_BROADCAST_CREATED = EVENT_TYPE_UNICAST_MAX + 1; Loading Loading @@ -90,6 +91,9 @@ public class LeAudioStackEvent { static final int DIRECTION_SINK = 1; static final int DIRECTION_SOURCE = 2; static final int GROUP_STREAM_STATUS_IDLE = 0; static final int GROUP_STREAM_STATUS_STREAMING = 1; public int type = EVENT_TYPE_NONE; public BluetoothDevice device; public int valueInt1 = 0; Loading Loading @@ -185,6 +189,8 @@ public class LeAudioStackEvent { return "EVENT_TYPE_HEALTH_BASED_GROUP_RECOMMENDATION"; case EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS: return "EVENT_TYPE_UNICAST_MONITOR_MODE_STATUS"; case EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED: return "EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED"; default: return "EVENT_TYPE_UNKNOWN:" + type; } Loading @@ -210,6 +216,8 @@ public class LeAudioStackEvent { 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_STREAM_STATUS_CHANGED: // same as EVENT_TYPE_GROUP_STATUS_CHANGED case EVENT_TYPE_GROUP_STATUS_CHANGED: return "{group_id:" + Integer.toString(value) + "}"; case EVENT_TYPE_AUDIO_CONF_CHANGED: Loading Loading @@ -300,6 +308,15 @@ public class LeAudioStackEvent { default: return "UNKNOWN"; } case EVENT_TYPE_GROUP_STREAM_STATUS_CHANGED: switch (value) { case GROUP_STREAM_STATUS_IDLE: return "GROUP_STREAM_STATUS_IDLE"; case GROUP_STREAM_STATUS_STREAMING: return "GROUP_STREAM_STATUS_STREAMING"; default: return "UNKNOWN"; } default: break; } Loading