diff options
| -rw-r--r-- | core/java/android/bluetooth/BluetoothCodecConfig.java | 13 | ||||
| -rw-r--r-- | core/jni/android_media_AudioSystem.cpp | 34 | ||||
| -rw-r--r-- | media/java/android/media/AudioManager.java | 29 | ||||
| -rw-r--r-- | media/java/android/media/AudioSystem.java | 28 |
4 files changed, 92 insertions, 12 deletions
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java index 79c0a3a207c4..c9d0ef247ca5 100644 --- a/core/java/android/bluetooth/BluetoothCodecConfig.java +++ b/core/java/android/bluetooth/BluetoothCodecConfig.java @@ -114,6 +114,19 @@ public final class BluetoothCodecConfig implements Parcelable { mCodecSpecific4 = codecSpecific4; } + @UnsupportedAppUsage + public BluetoothCodecConfig(int codecType) { + mCodecType = codecType; + mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; + mSampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE; + mBitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE; + mChannelMode = BluetoothCodecConfig.CHANNEL_MODE_NONE; + mCodecSpecific1 = 0; + mCodecSpecific2 = 0; + mCodecSpecific3 = 0; + mCodecSpecific4 = 0; + } + @Override public boolean equals(Object o) { if (o instanceof BluetoothCodecConfig) { diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp index 860de75787a7..9e32206aae90 100644 --- a/core/jni/android_media_AudioSystem.cpp +++ b/core/jni/android_media_AudioSystem.cpp @@ -2006,7 +2006,7 @@ android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMic std::vector<media::MicrophoneInfo> microphones; status_t status = AudioSystem::getMicrophones(µphones); if (status != NO_ERROR) { - ALOGE_IF(status != NO_ERROR, "AudioSystem::getMicrophones error %d", status); + ALOGE("AudioSystem::getMicrophones error %d", status); jStatus = nativeToJavaStatus(status); return jStatus; } @@ -2028,6 +2028,36 @@ android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMic } static jint +android_media_AudioSystem_getHwOffloadEncodingFormatsSupportedForA2DP( + JNIEnv *env, jobject thiz, jobject jEncodingFormatList) +{ + ALOGV("%s", __FUNCTION__); + jint jStatus = AUDIO_JAVA_SUCCESS; + if (!env->IsInstanceOf(jEncodingFormatList, gArrayListClass)) { + ALOGE("%s: jEncodingFormatList not an ArrayList", __FUNCTION__); + return (jint)AUDIO_JAVA_BAD_VALUE; + } + std::vector<audio_format_t> encodingFormats; + //FIXME: enable when native implementaiton is merged + //status_t status = AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP( + // &encodingFormats); + status_t status = NO_ERROR; + if (status != NO_ERROR) { + ALOGE("%s: error %d", __FUNCTION__, status); + jStatus = nativeToJavaStatus(status); + return jStatus; + } + + for (size_t i = 0; i < encodingFormats.size(); i++) { + ScopedLocalRef<jobject> jEncodingFormat( + env, env->NewObject(gIntegerClass, gIntegerCstor, encodingFormats[i])); + env->CallBooleanMethod(jEncodingFormatList, gArrayListMethods.add, + jEncodingFormat.get()); + } + return jStatus; +} + +static jint android_media_AudioSystem_getSurroundFormats(JNIEnv *env, jobject thiz, jobject jSurroundFormats, jboolean reported) { @@ -2199,6 +2229,8 @@ static const JNINativeMethod gMethods[] = { {"setAssistantUid", "(I)I", (void *)android_media_AudioSystem_setAssistantUid}, {"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}, }; static const JNINativeMethod gEventHandlerMethods[] = { diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 1883bf467a0f..1826b1b50fa2 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -28,6 +28,7 @@ import android.annotation.SystemService; import android.annotation.UnsupportedAppUsage; import android.app.NotificationManager; import android.app.PendingIntent; +import android.bluetooth.BluetoothCodecConfig; import android.bluetooth.BluetoothDevice; import android.content.ComponentName; import android.content.Context; @@ -4940,6 +4941,34 @@ public class AudioManager { return microphones; } + /** + * Returns a list of audio formats that corresponds to encoding formats + * supported on offload path for A2DP playback. + * + * @return a list of {@link BluetoothCodecConfig} objects containing encoding formats + * supported for offload A2DP playback + * @hide + */ + public List<BluetoothCodecConfig> getHwOffloadEncodingFormatsSupportedForA2DP() { + ArrayList<Integer> formatsList = new ArrayList<Integer>(); + ArrayList<BluetoothCodecConfig> codecConfigList = new ArrayList<BluetoothCodecConfig>(); + + int status = AudioSystem.getHwOffloadEncodingFormatsSupportedForA2DP(formatsList); + if (status != AudioManager.SUCCESS) { + Log.e(TAG, "getHwOffloadEncodingFormatsSupportedForA2DP failed:" + status); + return codecConfigList; + } + + for (Integer format : formatsList) { + int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format); + if (btSourceCodec + != BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) { + codecConfigList.add(new BluetoothCodecConfig(btSourceCodec)); + } + } + return codecConfigList; + } + // Since we need to calculate the changes since THE LAST NOTIFICATION, and not since the // (unpredictable) last time updateAudioPortCache() was called by someone, keep a list // of the ports that exist at the time of the last notification. diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index ddded5f02b48..0e05390ecf4b 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.UnsupportedAppUsage; +import android.bluetooth.BluetoothCodecConfig; import android.content.Context; import android.content.pm.PackageManager; import android.media.audiofx.AudioEffect; @@ -149,21 +150,20 @@ public class AudioSystem public static final int AUDIO_FORMAT_APTX_HD = 0x21000000; public static final int AUDIO_FORMAT_LDAC = 0x23000000; - /** converts audio format enum to string */ - public static String audioFormatToString(int audioFormat) { + /** + * Convert audio format enum values to Bluetooth codec values + */ + public static int audioFormatToBluetoothSourceCodec(int audioFormat) { switch (audioFormat) { - case AUDIO_FORMAT_INVALID: return "AUDIO_FORMAT_INVALID"; - case AUDIO_FORMAT_DEFAULT: return "AUDIO_FORMAT_DEFAULT"; - case AUDIO_FORMAT_AAC: return "AUDIO_FORMAT_AAC"; - case AUDIO_FORMAT_SBC: return "AUDIO_FORMAT_SBC"; - case AUDIO_FORMAT_APTX: return "AUDIO_FORMAT_APTX"; - case AUDIO_FORMAT_APTX_HD: return "AUDIO_FORMAT_APTX_HD"; - case AUDIO_FORMAT_LDAC: return "AUDIO_FORMAT_LDAC"; - default: return "unknown audio format (" + audioFormat + ")"; + case AUDIO_FORMAT_AAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC; + case AUDIO_FORMAT_SBC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC; + case AUDIO_FORMAT_APTX: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX; + case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD; + case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC; + default: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID; } } - /* Routing bits for the former setRouting/getRouting API */ /** @deprecated */ @Deprecated public static final int ROUTE_EARPIECE = (1 << 0); @@ -976,6 +976,12 @@ public class AudioSystem public static native int getSurroundFormats(Map<Integer, Boolean> surroundFormats, boolean reported); + /** + * Returns a list of audio formats (codec) supported on the A2DP offload path. + */ + public static native int getHwOffloadEncodingFormatsSupportedForA2DP( + ArrayList<Integer> formatList); + public static native int setSurroundFormatEnabled(int audioFormat, boolean enabled); /** |