Parse audio config codec capability for LE devices am: ae425ca614
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1881112 Change-Id: I7cab6bd9cc4bc2fbf6201c88b1f890a88a7c3bd2
This commit is contained in:
commit
b8fe694317
@ -9520,6 +9520,20 @@ package android.bluetooth {
|
||||
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED = "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED";
|
||||
}
|
||||
|
||||
public final class BluetoothLeAudioCodecConfig {
|
||||
method @NonNull public String getCodecName();
|
||||
method public int getCodecType();
|
||||
method public static int getMaxCodecType();
|
||||
field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240
|
||||
field public static final int SOURCE_CODEC_TYPE_LC3 = 0; // 0x0
|
||||
}
|
||||
|
||||
public static final class BluetoothLeAudioCodecConfig.Builder {
|
||||
ctor public BluetoothLeAudioCodecConfig.Builder();
|
||||
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig build();
|
||||
method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecType(int);
|
||||
}
|
||||
|
||||
public final class BluetoothManager {
|
||||
method public android.bluetooth.BluetoothAdapter getAdapter();
|
||||
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(int);
|
||||
|
129
core/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
Normal file
129
core/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.bluetooth;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Represents the codec configuration for a Bluetooth LE Audio source device.
|
||||
* <p>Contains the source codec type.
|
||||
* <p>The source codec type values are the same as those supported by the
|
||||
* device hardware.
|
||||
*
|
||||
* {@see BluetoothLeAudioCodecConfig}
|
||||
*/
|
||||
public final class BluetoothLeAudioCodecConfig {
|
||||
// Add an entry for each source codec here.
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = "SOURCE_CODEC_TYPE_", value = {
|
||||
SOURCE_CODEC_TYPE_LC3,
|
||||
SOURCE_CODEC_TYPE_INVALID
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface SourceCodecType {};
|
||||
|
||||
public static final int SOURCE_CODEC_TYPE_LC3 = 0;
|
||||
public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
|
||||
|
||||
/**
|
||||
* Represents the count of valid source codec types. Can be accessed via
|
||||
* {@link #getMaxCodecType}.
|
||||
*/
|
||||
private static final int SOURCE_CODEC_TYPE_MAX = 1;
|
||||
|
||||
private final @SourceCodecType int mCodecType;
|
||||
|
||||
/**
|
||||
* Creates a new BluetoothLeAudioCodecConfig.
|
||||
*
|
||||
* @param codecType the source codec type
|
||||
*/
|
||||
private BluetoothLeAudioCodecConfig(@SourceCodecType int codecType) {
|
||||
mCodecType = codecType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{codecName:" + getCodecName() + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the codec type.
|
||||
*
|
||||
* @return the codec type
|
||||
*/
|
||||
public @SourceCodecType int getCodecType() {
|
||||
return mCodecType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the valid codec types count.
|
||||
*/
|
||||
public static int getMaxCodecType() {
|
||||
return SOURCE_CODEC_TYPE_MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the codec name.
|
||||
*
|
||||
* @return the codec name
|
||||
*/
|
||||
public @NonNull String getCodecName() {
|
||||
switch (mCodecType) {
|
||||
case SOURCE_CODEC_TYPE_LC3:
|
||||
return "LC3";
|
||||
case SOURCE_CODEC_TYPE_INVALID:
|
||||
return "INVALID CODEC";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "UNKNOWN CODEC(" + mCodecType + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link BluetoothLeAudioCodecConfig}.
|
||||
* <p> By default, the codec type will be set to
|
||||
* {@link BluetoothLeAudioCodecConfig#SOURCE_CODEC_TYPE_INVALID}
|
||||
*/
|
||||
public static final class Builder {
|
||||
private int mCodecType = BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID;
|
||||
|
||||
/**
|
||||
* Set codec type for Bluetooth codec config.
|
||||
*
|
||||
* @param codecType of this codec
|
||||
* @return the same Builder instance
|
||||
*/
|
||||
public @NonNull Builder setCodecType(@SourceCodecType int codecType) {
|
||||
mCodecType = codecType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build {@link BluetoothLeAudioCodecConfig}.
|
||||
* @return new BluetoothLeAudioCodecConfig built
|
||||
*/
|
||||
public @NonNull BluetoothLeAudioCodecConfig build() {
|
||||
return new BluetoothLeAudioCodecConfig(mCodecType);
|
||||
}
|
||||
}
|
||||
}
|
@ -2273,10 +2273,8 @@ android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMic
|
||||
return jStatus;
|
||||
}
|
||||
|
||||
static jint
|
||||
android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(
|
||||
JNIEnv *env, jobject thiz, jobject jEncodingFormatList)
|
||||
{
|
||||
static jint android_media_AudioSystem_getHwOffloadFormatsSupportedForBluetoothMedia(
|
||||
JNIEnv *env, jobject thiz, jint deviceType, jobject jEncodingFormatList) {
|
||||
ALOGV("%s", __FUNCTION__);
|
||||
jint jStatus = AUDIO_JAVA_SUCCESS;
|
||||
if (!env->IsInstanceOf(jEncodingFormatList, gArrayListClass)) {
|
||||
@ -2284,8 +2282,10 @@ android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP(
|
||||
return (jint)AUDIO_JAVA_BAD_VALUE;
|
||||
}
|
||||
std::vector<audio_format_t> encodingFormats;
|
||||
status_t status = AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
|
||||
&encodingFormats);
|
||||
status_t status =
|
||||
AudioSystem::getHwOffloadFormatsSupportedForBluetoothMedia(static_cast<audio_devices_t>(
|
||||
deviceType),
|
||||
&encodingFormats);
|
||||
if (status != NO_ERROR) {
|
||||
ALOGE("%s: error %d", __FUNCTION__, status);
|
||||
jStatus = nativeToJavaStatus(status);
|
||||
@ -2810,8 +2810,8 @@ static const JNINativeMethod gMethods[] =
|
||||
{"setA11yServicesUids", "([I)I", (void *)android_media_AudioSystem_setA11yServicesUids},
|
||||
{"isHapticPlaybackSupported", "()Z",
|
||||
(void *)android_media_AudioSystem_isHapticPlaybackSupported},
|
||||
{"getHwOffloadEncodingFormatsSupportedForA2DP", "(Ljava/util/ArrayList;)I",
|
||||
(void *)android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP},
|
||||
{"getHwOffloadFormatsSupportedForBluetoothMedia", "(ILjava/util/ArrayList;)I",
|
||||
(void *)android_media_AudioSystem_getHwOffloadFormatsSupportedForBluetoothMedia},
|
||||
{"setSupportedSystemUsages", "([I)I",
|
||||
(void *)android_media_AudioSystem_setSupportedSystemUsages},
|
||||
{"setAllowedCapturePolicy", "(II)I",
|
||||
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.bluetooth;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Unit test cases for {@link BluetoothLeAudioCodecConfig}.
|
||||
*/
|
||||
public class BluetoothLeAudioCodecConfigTest extends TestCase {
|
||||
private int[] mCodecTypeArray = new int[] {
|
||||
BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3,
|
||||
BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID,
|
||||
};
|
||||
|
||||
@SmallTest
|
||||
public void testBluetoothLeAudioCodecConfig_valid_get_methods() {
|
||||
|
||||
for (int codecIdx = 0; codecIdx < mCodecTypeArray.length; codecIdx++) {
|
||||
int codecType = mCodecTypeArray[codecIdx];
|
||||
|
||||
BluetoothLeAudioCodecConfig leAudioCodecConfig =
|
||||
buildBluetoothLeAudioCodecConfig(codecType);
|
||||
|
||||
if (codecType == BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3) {
|
||||
assertEquals("LC3", leAudioCodecConfig.getCodecName());
|
||||
}
|
||||
if (codecType == BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
|
||||
assertEquals("INVALID CODEC", leAudioCodecConfig.getCodecName());
|
||||
}
|
||||
|
||||
assertEquals(1, leAudioCodecConfig.getMaxCodecType());
|
||||
assertEquals(codecType, leAudioCodecConfig.getCodecType());
|
||||
}
|
||||
}
|
||||
|
||||
private BluetoothLeAudioCodecConfig buildBluetoothLeAudioCodecConfig(int sourceCodecType) {
|
||||
return new BluetoothLeAudioCodecConfig.Builder()
|
||||
.setCodecType(sourceCodecType)
|
||||
.build();
|
||||
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.bluetooth.BluetoothCodecConfig;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothLeAudioCodecConfig;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@ -6790,30 +6791,56 @@ public class AudioManager {
|
||||
|
||||
/**
|
||||
* Returns a list of audio formats that corresponds to encoding formats
|
||||
* supported on offload path for A2DP playback.
|
||||
* supported on offload path for A2DP and LE audio playback.
|
||||
*
|
||||
* @param deviceType Indicates the target device type {@link AudioSystem.DeviceType}
|
||||
* @return a list of {@link BluetoothCodecConfig} objects containing encoding formats
|
||||
* supported for offload A2DP playback
|
||||
* supported for offload A2DP playback or a list of {@link BluetoothLeAudioCodecConfig}
|
||||
* objects containing encoding formats supported for offload LE Audio playback
|
||||
* @hide
|
||||
*/
|
||||
public List<BluetoothCodecConfig> getHwOffloadEncodingFormatsSupportedForA2DP() {
|
||||
public List<?> getHwOffloadFormatsSupportedForBluetoothMedia(
|
||||
@AudioSystem.DeviceType int deviceType) {
|
||||
ArrayList<Integer> formatsList = new ArrayList<Integer>();
|
||||
ArrayList<BluetoothCodecConfig> codecConfigList = new ArrayList<BluetoothCodecConfig>();
|
||||
ArrayList<BluetoothCodecConfig> a2dpCodecConfigList = new ArrayList<BluetoothCodecConfig>();
|
||||
ArrayList<BluetoothLeAudioCodecConfig> leAudioCodecConfigList =
|
||||
new ArrayList<BluetoothLeAudioCodecConfig>();
|
||||
|
||||
int status = AudioSystem.getHwOffloadEncodingFormatsSupportedForA2DP(formatsList);
|
||||
if (deviceType != AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP
|
||||
&& deviceType != AudioSystem.DEVICE_OUT_BLE_HEADSET) {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal devicetype for the getHwOffloadFormatsSupportedForBluetoothMedia");
|
||||
}
|
||||
|
||||
int status = AudioSystem.getHwOffloadFormatsSupportedForBluetoothMedia(deviceType,
|
||||
formatsList);
|
||||
if (status != AudioManager.SUCCESS) {
|
||||
Log.e(TAG, "getHwOffloadEncodingFormatsSupportedForA2DP failed:" + status);
|
||||
return codecConfigList;
|
||||
Log.e(TAG, "getHwOffloadFormatsSupportedForBluetoothMedia for deviceType "
|
||||
+ deviceType + " failed:" + status);
|
||||
return a2dpCodecConfigList;
|
||||
}
|
||||
|
||||
for (Integer format : formatsList) {
|
||||
int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format);
|
||||
if (btSourceCodec
|
||||
!= BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
|
||||
codecConfigList.add(new BluetoothCodecConfig(btSourceCodec));
|
||||
if (deviceType == AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP) {
|
||||
for (Integer format : formatsList) {
|
||||
int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format);
|
||||
if (btSourceCodec != BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
|
||||
a2dpCodecConfigList.add(new BluetoothCodecConfig(btSourceCodec));
|
||||
}
|
||||
}
|
||||
return a2dpCodecConfigList;
|
||||
} else if (deviceType == AudioSystem.DEVICE_OUT_BLE_HEADSET) {
|
||||
for (Integer format : formatsList) {
|
||||
int btLeAudioCodec = AudioSystem.audioFormatToBluetoothLeAudioSourceCodec(format);
|
||||
if (btLeAudioCodec != BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
|
||||
leAudioCodecConfigList.add(new BluetoothLeAudioCodecConfig.Builder()
|
||||
.setCodecType(btLeAudioCodec)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
return leAudioCodecConfigList;
|
||||
}
|
||||
return codecConfigList;
|
||||
Log.e(TAG, "Input deviceType " + deviceType + " doesn't support.");
|
||||
return a2dpCodecConfigList;
|
||||
}
|
||||
|
||||
// Since we need to calculate the changes since THE LAST NOTIFICATION, and not since the
|
||||
|
@ -21,6 +21,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.TestApi;
|
||||
import android.bluetooth.BluetoothCodecConfig;
|
||||
import android.bluetooth.BluetoothLeAudioCodecConfig;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
@ -229,6 +230,9 @@ public class AudioSystem
|
||||
public static final int AUDIO_FORMAT_APTX_HD = 0x21000000;
|
||||
/** @hide */
|
||||
public static final int AUDIO_FORMAT_LDAC = 0x23000000;
|
||||
/** @hide */
|
||||
public static final int AUDIO_FORMAT_LC3 = 0x2B000000;
|
||||
|
||||
|
||||
/** @hide */
|
||||
@IntDef(flag = false, prefix = "AUDIO_FORMAT_", value = {
|
||||
@ -238,11 +242,26 @@ public class AudioSystem
|
||||
AUDIO_FORMAT_SBC,
|
||||
AUDIO_FORMAT_APTX,
|
||||
AUDIO_FORMAT_APTX_HD,
|
||||
AUDIO_FORMAT_LDAC }
|
||||
AUDIO_FORMAT_LDAC}
|
||||
)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AudioFormatNativeEnumForBtCodec {}
|
||||
|
||||
/** @hide */
|
||||
@IntDef(flag = false, prefix = "AUDIO_FORMAT_", value = {
|
||||
AUDIO_FORMAT_LC3}
|
||||
)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AudioFormatNativeEnumForBtLeAudioCodec {}
|
||||
|
||||
/** @hide */
|
||||
@IntDef(flag = false, prefix = "DEVICE_", value = {
|
||||
DEVICE_OUT_BLUETOOTH_A2DP,
|
||||
DEVICE_OUT_BLE_HEADSET}
|
||||
)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface DeviceType {}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Convert audio format enum values to Bluetooth codec values
|
||||
@ -262,6 +281,21 @@ public class AudioSystem
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Convert audio format enum values to Bluetooth LE audio codec values
|
||||
*/
|
||||
public static int audioFormatToBluetoothLeAudioSourceCodec(
|
||||
@AudioFormatNativeEnumForBtLeAudioCodec int audioFormat) {
|
||||
switch (audioFormat) {
|
||||
case AUDIO_FORMAT_LC3: return BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3;
|
||||
default:
|
||||
Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat)
|
||||
+ " for conversion to BT LE audio codec");
|
||||
return BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Convert a Bluetooth codec to an audio format enum
|
||||
@ -1754,10 +1788,10 @@ public class AudioSystem
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* Returns a list of audio formats (codec) supported on the A2DP offload path.
|
||||
* Returns a list of audio formats (codec) supported on the A2DP and LE audio offload path.
|
||||
*/
|
||||
public static native int getHwOffloadEncodingFormatsSupportedForA2DP(
|
||||
ArrayList<Integer> formatList);
|
||||
public static native int getHwOffloadFormatsSupportedForBluetoothMedia(
|
||||
@DeviceType int deviceType, ArrayList<Integer> formatList);
|
||||
|
||||
/** @hide */
|
||||
public static native int setSurroundFormatEnabled(int audioFormat, boolean enabled);
|
||||
|
Loading…
x
Reference in New Issue
Block a user