fix: 首次提交
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.bluetooth.BluetoothLeAudioCodecConfigMetadata
|
||||
import android.bluetooth.BluetoothLeAudioContentMetadata
|
||||
import android.bluetooth.BluetoothLeBroadcastChannel
|
||||
import android.bluetooth.BluetoothLeBroadcastMetadata
|
||||
import android.bluetooth.BluetoothLeBroadcastSubgroup
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt.toQrCodeString
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class BluetoothLeBroadcastMetadataExtTest {
|
||||
|
||||
@Test
|
||||
fun toQrCodeString_encrypted() {
|
||||
val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
|
||||
setCodecId(0x6)
|
||||
val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
|
||||
setCodecSpecificConfig(audioCodecConfigMetadata)
|
||||
setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
|
||||
.setProgramInfo("Test").setLanguage("eng").build())
|
||||
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
|
||||
setSelected(true)
|
||||
setChannelIndex(2)
|
||||
setCodecMetadata(audioCodecConfigMetadata)
|
||||
}.build())
|
||||
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
|
||||
setSelected(true)
|
||||
setChannelIndex(1)
|
||||
setCodecMetadata(audioCodecConfigMetadata)
|
||||
}.build())
|
||||
}.build()
|
||||
|
||||
val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
|
||||
setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
|
||||
setSourceAdvertisingSid(1)
|
||||
setBroadcastId(123456)
|
||||
setBroadcastName("Test")
|
||||
setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
|
||||
.setProgramInfo("pTest").build())
|
||||
setPaSyncInterval(160)
|
||||
setEncrypted(true)
|
||||
setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
|
||||
addSubgroup(subgroup)
|
||||
}.build()
|
||||
|
||||
val qrCodeString = metadata.toQrCodeString()
|
||||
|
||||
assertThat(qrCodeString).isEqualTo(QR_CODE_STRING)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toQrCodeString_non_encrypted() {
|
||||
val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
|
||||
setCodecId(0x6)
|
||||
val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
|
||||
setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
|
||||
.build())
|
||||
setCodecSpecificConfig(audioCodecConfigMetadata)
|
||||
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
|
||||
setSelected(true)
|
||||
setChannelIndex(1)
|
||||
setCodecMetadata(audioCodecConfigMetadata)
|
||||
}.build())
|
||||
}.build()
|
||||
|
||||
val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
|
||||
setSourceDevice(DevicePublic, BluetoothDevice.ADDRESS_TYPE_PUBLIC)
|
||||
setSourceAdvertisingSid(1)
|
||||
setBroadcastId(0xDE51E9)
|
||||
setBroadcastName("Hockey")
|
||||
setAudioConfigQuality(BluetoothLeBroadcastMetadata.AUDIO_CONFIG_QUALITY_STANDARD)
|
||||
setPaSyncInterval(0xFFFF)
|
||||
setEncrypted(false)
|
||||
addSubgroup(subgroup)
|
||||
}.build()
|
||||
|
||||
val qrCodeString = metadata.toQrCodeString()
|
||||
|
||||
assertThat(qrCodeString).isEqualTo(QR_CODE_STRING_NON_ENCRYPTED)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toQrCodeString_NoChannelSelected() {
|
||||
val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
|
||||
setCodecId(0x6)
|
||||
val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
|
||||
setCodecSpecificConfig(audioCodecConfigMetadata)
|
||||
setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
|
||||
.setProgramInfo("Test").setLanguage("eng").build())
|
||||
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
|
||||
setSelected(false)
|
||||
setChannelIndex(2)
|
||||
setCodecMetadata(audioCodecConfigMetadata)
|
||||
}.build())
|
||||
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
|
||||
setSelected(false)
|
||||
setChannelIndex(1)
|
||||
setCodecMetadata(audioCodecConfigMetadata)
|
||||
}.build())
|
||||
}.build()
|
||||
|
||||
val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
|
||||
setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
|
||||
setSourceAdvertisingSid(1)
|
||||
setBroadcastId(123456)
|
||||
setBroadcastName("Test")
|
||||
setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
|
||||
.setProgramInfo("pTest").build())
|
||||
setPaSyncInterval(160)
|
||||
setEncrypted(true)
|
||||
setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
|
||||
addSubgroup(subgroup)
|
||||
}.build()
|
||||
|
||||
// if no channel is selected, no preference(0xFFFFFFFFu) will be set in BIS
|
||||
val qrCodeString = metadata.toQrCodeString()
|
||||
|
||||
val parsedMetadata =
|
||||
BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(qrCodeString)!!
|
||||
|
||||
assertThat(parsedMetadata).isNotNull()
|
||||
assertThat(parsedMetadata.subgroups).isNotNull()
|
||||
assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
|
||||
assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
|
||||
assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(1)
|
||||
assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isFalse()
|
||||
// placeholder channel with not selected
|
||||
assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(1)
|
||||
assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toQrCodeString_OneChannelSelected() {
|
||||
val subgroup = BluetoothLeBroadcastSubgroup.Builder().apply {
|
||||
setCodecId(0x6)
|
||||
val audioCodecConfigMetadata = BluetoothLeAudioCodecConfigMetadata.Builder().build()
|
||||
setCodecSpecificConfig(audioCodecConfigMetadata)
|
||||
setContentMetadata(BluetoothLeAudioContentMetadata.Builder()
|
||||
.setProgramInfo("Test").setLanguage("eng").build())
|
||||
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
|
||||
setSelected(false)
|
||||
setChannelIndex(1)
|
||||
setCodecMetadata(audioCodecConfigMetadata)
|
||||
}.build())
|
||||
addChannel(BluetoothLeBroadcastChannel.Builder().apply {
|
||||
setSelected(true)
|
||||
setChannelIndex(2)
|
||||
setCodecMetadata(audioCodecConfigMetadata)
|
||||
}.build())
|
||||
}.build()
|
||||
|
||||
val metadata = BluetoothLeBroadcastMetadata.Builder().apply {
|
||||
setSourceDevice(Device, BluetoothDevice.ADDRESS_TYPE_RANDOM)
|
||||
setSourceAdvertisingSid(1)
|
||||
setBroadcastId(123456)
|
||||
setBroadcastName("Test")
|
||||
setPublicBroadcastMetadata(BluetoothLeAudioContentMetadata.Builder()
|
||||
.setProgramInfo("pTest").build())
|
||||
setPaSyncInterval(160)
|
||||
setEncrypted(true)
|
||||
setBroadcastCode("TestCode".toByteArray(Charsets.UTF_8))
|
||||
addSubgroup(subgroup)
|
||||
}.build()
|
||||
|
||||
val qrCodeString = metadata.toQrCodeString()
|
||||
|
||||
val parsedMetadata =
|
||||
BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(qrCodeString)!!
|
||||
|
||||
assertThat(parsedMetadata).isNotNull()
|
||||
assertThat(parsedMetadata.subgroups).isNotNull()
|
||||
assertThat(parsedMetadata.subgroups.size).isEqualTo(1)
|
||||
assertThat(parsedMetadata.subgroups[0].channels).isNotNull()
|
||||
// Only selected channel can be recovered, non-selected ones will be ignored
|
||||
assertThat(parsedMetadata.subgroups[0].channels.size).isEqualTo(1)
|
||||
assertThat(parsedMetadata.subgroups[0].hasChannelPreference()).isTrue()
|
||||
assertThat(parsedMetadata.subgroups[0].channels[0].channelIndex).isEqualTo(2)
|
||||
assertThat(parsedMetadata.subgroups[0].channels[0].isSelected).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decodeAndEncodeAgain_sameString() {
|
||||
val metadata = BluetoothLeBroadcastMetadataExt.convertToBroadcastMetadata(QR_CODE_STRING)!!
|
||||
|
||||
val qrCodeString = metadata.toQrCodeString()
|
||||
|
||||
assertThat(qrCodeString).isEqualTo(QR_CODE_STRING)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun decodeAndEncodeAgain_sameString_non_encrypted() {
|
||||
val metadata =
|
||||
BluetoothLeBroadcastMetadataExt
|
||||
.convertToBroadcastMetadata(QR_CODE_STRING_NON_ENCRYPTED)!!
|
||||
|
||||
val qrCodeString = metadata.toQrCodeString()
|
||||
|
||||
assertThat(qrCodeString).isEqualTo(QR_CODE_STRING_NON_ENCRYPTED)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"
|
||||
const val TEST_DEVICE_ADDRESS_PUBLIC = "AA:BB:CC:00:11:22"
|
||||
|
||||
val Device: BluetoothDevice =
|
||||
BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(TEST_DEVICE_ADDRESS,
|
||||
BluetoothDevice.ADDRESS_TYPE_RANDOM)
|
||||
|
||||
val DevicePublic: BluetoothDevice =
|
||||
BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(TEST_DEVICE_ADDRESS_PUBLIC,
|
||||
BluetoothDevice.ADDRESS_TYPE_PUBLIC)
|
||||
|
||||
const val QR_CODE_STRING =
|
||||
"BLUETOOTH:UUID:184F;BN:VGVzdA==;AT:1;AD:00A1A1A1A1A1;BI:1E240;BC:VGVzdENvZGU=;" +
|
||||
"MD:BgNwVGVzdA==;AS:1;PI:A0;NS:1;BS:3;NB:2;SM:BQNUZXN0BARlbmc=;;"
|
||||
const val QR_CODE_STRING_NON_ENCRYPTED =
|
||||
"BLUETOOTH:UUID:184F;BN:SG9ja2V5;AT:0;AD:AABBCC001122;BI:DE51E9;SQ:1;AS:1;PI:FFFF;" +
|
||||
"NS:1;BS:1;NB:1;;"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user