summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveData.kt90
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveDataTest.kt124
3 files changed, 217 insertions, 0 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index 08f7806207db..f22bdaf55ce4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -89,11 +89,14 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
"com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_STATE_CHANGE";
public static final String ACTION_LE_AUDIO_SHARING_DEVICE_CONNECTED =
"com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_DEVICE_CONNECTED";
+ public static final String ACTION_LE_AUDIO_PRIVATE_BROADCAST_RECEIVED =
+ "com.android.settings.action.BLUETOOTH_LE_AUDIO_PRIVATE_BROADCAST_RECEIVED";
public static final String EXTRA_LE_AUDIO_SHARING_STATE = "BLUETOOTH_LE_AUDIO_SHARING_STATE";
public static final String EXTRA_BLUETOOTH_DEVICE = "BLUETOOTH_DEVICE";
public static final String EXTRA_BT_DEVICE_TO_AUTO_ADD_SOURCE = "BT_DEVICE_TO_AUTO_ADD_SOURCE";
public static final String EXTRA_START_LE_AUDIO_SHARING = "START_LE_AUDIO_SHARING";
public static final String EXTRA_PAIR_AND_JOIN_SHARING = "PAIR_AND_JOIN_SHARING";
+ public static final String EXTRA_PRIVATE_BROADCAST_RECEIVE_DATA = "RECEIVE_DATA";
public static final String BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID =
"bluetooth_le_broadcast_primary_device_group_id";
public static final int BROADCAST_STATE_UNKNOWN = 0;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveData.kt b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveData.kt
new file mode 100644
index 000000000000..a284d2010195
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveData.kt
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth
+
+import android.bluetooth.BluetoothDevice
+import android.os.Parcel
+import android.os.Parcelable
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED
+
+/**
+ * Data class representing information received in a private broadcast.
+ * This class encapsulates details about the sink device, source ID, broadcast ID, and the
+ * broadcast source state.
+ *
+ * @param sink The [BluetoothDevice] acting as the sink.
+ * @param sourceId The ID of the audio source.
+ * @param broadcastId The ID of the broadcast source.
+ * @param programInfo The program info string of the broadcast source.
+ * @param state The current state of the broadcast source.
+ */
+data class PrivateBroadcastReceiveData(
+ val sink: BluetoothDevice?,
+ val sourceId: Int = -1,
+ val broadcastId: Int = -1,
+ val programInfo: String = "",
+ val state: LocalBluetoothLeBroadcastSourceState?,
+) : Parcelable {
+
+ override fun describeContents(): Int = 0
+
+ override fun writeToParcel(parcel: Parcel, flags: Int) {
+ parcel.writeParcelable(sink, flags)
+ parcel.writeInt(sourceId)
+ parcel.writeInt(broadcastId)
+ parcel.writeString(programInfo)
+ parcel.writeSerializable(state)
+ }
+
+ companion object {
+ @JvmField
+ val CREATOR: Parcelable.Creator<PrivateBroadcastReceiveData> =
+ object : Parcelable.Creator<PrivateBroadcastReceiveData> {
+ override fun createFromParcel(parcel: Parcel) =
+ parcel.run {
+ PrivateBroadcastReceiveData(
+ sink = readParcelable(
+ BluetoothDevice::class.java.classLoader,
+ BluetoothDevice::class.java
+ ),
+ sourceId = readInt(),
+ broadcastId = readInt(),
+ programInfo = readString() ?: "",
+ state = readSerializable(
+ LocalBluetoothLeBroadcastSourceState::class.java.classLoader,
+ LocalBluetoothLeBroadcastSourceState::class.java
+ )
+ )
+ }
+ override fun newArray(size: Int): Array<PrivateBroadcastReceiveData?> {
+ return arrayOfNulls(size)
+ }
+ }
+
+ fun PrivateBroadcastReceiveData.isValid(): Boolean {
+ return sink != null
+ && sourceId != -1
+ && broadcastId != -1
+ && (state == STREAMING
+ || state == PAUSED
+ || state == DECRYPTION_FAILED)
+ }
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveDataTest.kt b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveDataTest.kt
new file mode 100644
index 000000000000..5fd67a16a305
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/PrivateBroadcastReceiveDataTest.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth
+
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
+import android.os.Parcel
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState
+import com.android.settingslib.bluetooth.PrivateBroadcastReceiveData.Companion.isValid
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.robolectric.RobolectricTestRunner
+
+@RunWith(RobolectricTestRunner::class)
+class PrivateBroadcastReceiveDataTest {
+
+ @Test
+ fun parcelable() {
+ val original = PrivateBroadcastReceiveData(
+ sink = sink,
+ sourceId = 1,
+ broadcastId = 2,
+ programInfo = "Test Program",
+ state = LocalBluetoothLeBroadcastSourceState.STREAMING
+ )
+
+ val parcel = Parcel.obtain()
+ original.writeToParcel(parcel, 0)
+ parcel.setDataPosition(0)
+
+ val recreated = PrivateBroadcastReceiveData.CREATOR.createFromParcel(parcel)
+
+ assertEquals(original, recreated)
+ }
+
+ @Test
+ fun isValid_validData() {
+ val data = PrivateBroadcastReceiveData(
+ sink = sink,
+ sourceId = 1,
+ broadcastId = 2,
+ state = LocalBluetoothLeBroadcastSourceState.STREAMING
+ )
+ assertTrue(data.isValid())
+ }
+
+ @Test
+ fun isValid_nullSink() {
+ val data = PrivateBroadcastReceiveData(
+ sink = null,
+ sourceId = 1,
+ broadcastId = 2,
+ state = LocalBluetoothLeBroadcastSourceState.STREAMING
+ )
+ assertFalse(data.isValid())
+ }
+
+ @Test
+ fun isValid_invalidSourceId() {
+ val data = PrivateBroadcastReceiveData(
+ sink = sink,
+ sourceId = -1,
+ broadcastId = 2,
+ state = LocalBluetoothLeBroadcastSourceState.STREAMING
+ )
+ assertFalse(data.isValid())
+ }
+
+ @Test
+ fun isValid_invalidBroadcastId() {
+ val data = PrivateBroadcastReceiveData(
+ sink = sink,
+ sourceId = 1,
+ broadcastId = -1,
+ state = LocalBluetoothLeBroadcastSourceState.STREAMING
+ )
+ assertFalse(data.isValid())
+ }
+
+ @Test
+ fun isValid_nullState() {
+ val data = PrivateBroadcastReceiveData(
+ sink = sink,
+ sourceId = 1,
+ broadcastId = 2,
+ state = null
+ )
+ assertFalse(data.isValid())
+ }
+
+ @Test
+ fun isValid_correctStates() {
+ assertTrue(PrivateBroadcastReceiveData(sink, 1, 1, state = LocalBluetoothLeBroadcastSourceState.STREAMING).isValid())
+ assertTrue(PrivateBroadcastReceiveData(sink, 1, 1, state = LocalBluetoothLeBroadcastSourceState.PAUSED).isValid())
+ assertTrue(PrivateBroadcastReceiveData(sink, 1, 1, state = LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED).isValid())
+ }
+
+ private companion object {
+ const val TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"
+
+ val sink: BluetoothDevice =
+ BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(
+ TEST_DEVICE_ADDRESS,
+ BluetoothDevice.ADDRESS_TYPE_RANDOM
+ )
+ }
+}