summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Aniket Kumar Lata <alata@quicinc.com> 2019-01-11 02:02:33 -0800
committer Eric Laurent <elaurent@google.com> 2019-01-17 14:48:27 -0800
commit9fbc205fdc67b2dbc8ccfc4325fb60475f020983 (patch)
treef4602d58b0ac8cf0d5a77f4259e44964c499f18a
parent37f2ba0a3fdd5e042622e62bf1783bfcd74b5949 (diff)
audio: Send A2DP codec to AudioSystem on connection state change
Add A2DP codec parameter to AudioSystem and AudioService APIs for connection state change and device config change. Update native interface to pass codec parameter. Bug: 111812273 Test: make Change-Id: I9bcc9c97241a2ac2d941ae6902469ef9957a993c
-rw-r--r--core/jni/android_media_AudioSystem.cpp10
-rw-r--r--media/java/android/media/AudioSystem.java30
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java234
3 files changed, 207 insertions, 67 deletions
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 80560f826235..860de75787a7 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -487,7 +487,8 @@ android_media_AudioSystem_recording_callback(int event,
}
static jint
-android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name)
+android_media_AudioSystem_setDeviceConnectionState(JNIEnv *env, jobject thiz, jint device, jint state, jstring device_address, jstring device_name,
+ jint codec __unused)
{
const char *c_address = env->GetStringUTFChars(device_address, NULL);
const char *c_name = env->GetStringUTFChars(device_name, NULL);
@@ -510,7 +511,8 @@ android_media_AudioSystem_getDeviceConnectionState(JNIEnv *env, jobject thiz, ji
}
static jint
-android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name)
+android_media_AudioSystem_handleDeviceConfigChange(JNIEnv *env, jobject thiz, jint device, jstring device_address, jstring device_name,
+ jint codec __unused)
{
const char *c_address = env->GetStringUTFChars(device_address, NULL);
const char *c_name = env->GetStringUTFChars(device_name, NULL);
@@ -2142,9 +2144,9 @@ static const JNINativeMethod gMethods[] = {
{"isSourceActive", "(I)Z", (void *)android_media_AudioSystem_isSourceActive},
{"newAudioSessionId", "()I", (void *)android_media_AudioSystem_newAudioSessionId},
{"newAudioPlayerId", "()I", (void *)android_media_AudioSystem_newAudioPlayerId},
- {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
+ {"setDeviceConnectionState", "(IILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_setDeviceConnectionState},
{"getDeviceConnectionState", "(ILjava/lang/String;)I", (void *)android_media_AudioSystem_getDeviceConnectionState},
- {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
+ {"handleDeviceConfigChange", "(ILjava/lang/String;Ljava/lang/String;I)I", (void *)android_media_AudioSystem_handleDeviceConfigChange},
{"setPhoneState", "(I)I", (void *)android_media_AudioSystem_setPhoneState},
{"setForceUse", "(II)I", (void *)android_media_AudioSystem_setForceUse},
{"getForceUse", "(I)I", (void *)android_media_AudioSystem_getForceUse},
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index de73649d59dc..ddded5f02b48 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -140,6 +140,30 @@ public class AudioSystem
}
}
+ /* Formats for A2DP codecs, must match system/audio-base.h audio_format_t */
+ public static final int AUDIO_FORMAT_INVALID = 0xFFFFFFFF;
+ public static final int AUDIO_FORMAT_DEFAULT = 0;
+ public static final int AUDIO_FORMAT_AAC = 0x04000000;
+ public static final int AUDIO_FORMAT_SBC = 0x1F000000;
+ public static final int AUDIO_FORMAT_APTX = 0x20000000;
+ 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) {
+ 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 + ")";
+ }
+ }
+
+
/* Routing bits for the former setRouting/getRouting API */
/** @deprecated */
@Deprecated public static final int ROUTE_EARPIECE = (1 << 0);
@@ -860,12 +884,14 @@ public class AudioSystem
*/
@UnsupportedAppUsage
public static native int setDeviceConnectionState(int device, int state,
- String device_address, String device_name);
+ String device_address, String device_name,
+ int codecFormat);
@UnsupportedAppUsage
public static native int getDeviceConnectionState(int device, String device_address);
public static native int handleDeviceConfigChange(int device,
String device_address,
- String device_name);
+ String device_name,
+ int codecFormat);
@UnsupportedAppUsage
public static native int setPhoneState(int state);
@UnsupportedAppUsage
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 9a4ca1f954d0..1662fce31ff4 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -38,6 +38,8 @@ import android.app.NotificationManager;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
@@ -480,16 +482,20 @@ public class AudioService extends IAudioService.Stub
int mDeviceType;
String mDeviceName;
String mDeviceAddress;
+ int mDeviceCodecFormat;
- public DeviceListSpec(int deviceType, String deviceName, String deviceAddress) {
+ DeviceListSpec(int deviceType, String deviceName, String deviceAddress,
+ int deviceCodecFormat) {
mDeviceType = deviceType;
mDeviceName = deviceName;
mDeviceAddress = deviceAddress;
+ mDeviceCodecFormat = deviceCodecFormat;
}
public String toString() {
return "[type:0x" + Integer.toHexString(mDeviceType) + " name:" + mDeviceName
- + " address:" + mDeviceAddress + "]";
+ + " address:" + mDeviceAddress
+ + " codec: " + Integer.toHexString(mDeviceCodecFormat) + "]";
}
}
@@ -501,6 +507,52 @@ public class AudioService extends IAudioService.Stub
private final ArrayMap<String, DeviceListSpec> mConnectedDevices = new ArrayMap<>();
+ private class BluetoothA2dpDeviceInfo {
+ BluetoothDevice mBtDevice;
+ int mVolume;
+ int mCodec;
+
+ BluetoothA2dpDeviceInfo(BluetoothDevice btDevice) {
+ this(btDevice, -1, AudioSystem.AUDIO_FORMAT_DEFAULT);
+ }
+
+ BluetoothA2dpDeviceInfo(BluetoothDevice btDevice,
+ int volume, int codec) {
+ mBtDevice = btDevice;
+ mVolume = volume;
+ mCodec = codec;
+ }
+
+ public BluetoothDevice getBtDevice() {
+ return mBtDevice;
+ }
+
+ public int getVolume() {
+ return mVolume;
+ }
+
+ public int getCodec() {
+ return mCodec;
+ }
+ }
+
+ private int mapBluetoothCodecToAudioFormat(int btCodecType) {
+ switch (btCodecType) {
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
+ return AudioSystem.AUDIO_FORMAT_SBC;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
+ return AudioSystem.AUDIO_FORMAT_AAC;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
+ return AudioSystem.AUDIO_FORMAT_APTX;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
+ return AudioSystem.AUDIO_FORMAT_APTX_HD;
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
+ return AudioSystem.AUDIO_FORMAT_LDAC;
+ default:
+ return AudioSystem.AUDIO_FORMAT_DEFAULT;
+ }
+ }
+
// Forced device usage for communications
private int mForcedUseForComm;
private int mForcedUseForCommExt; // External state returned by getters: always consistent
@@ -1020,7 +1072,8 @@ public class AudioService extends IAudioService.Stub
spec.mDeviceType,
AudioSystem.DEVICE_STATE_AVAILABLE,
spec.mDeviceAddress,
- spec.mDeviceName);
+ spec.mDeviceName,
+ spec.mDeviceCodecFormat);
}
}
// Restore call state
@@ -3904,8 +3957,8 @@ public class AudioService extends IAudioService.Stub
queueMsgUnderWakeLock(mAudioHandler,
MSG_SET_A2DP_SINK_CONNECTION_STATE,
state,
- -1,
- btDevice,
+ 0 /* arg2 unused */,
+ new BluetoothA2dpDeviceInfo(btDevice),
delay);
}
}
@@ -3922,7 +3975,7 @@ public class AudioService extends IAudioService.Stub
MSG_SET_A2DP_SRC_CONNECTION_STATE,
state,
0 /* arg2 unused */,
- btDevice,
+ new BluetoothA2dpDeviceInfo(btDevice),
0 /* delay */);
}
}
@@ -4687,6 +4740,17 @@ public class AudioService extends IAudioService.Stub
}
}
+ private int getA2dpCodec(BluetoothDevice device) {
+ synchronized (mA2dpAvrcpLock) {
+ if (mA2dp != null) {
+ BluetoothCodecStatus btCodecStatus = mA2dp.getCodecStatus(device);
+ BluetoothCodecConfig btCodecConfig = btCodecStatus.getCodecConfig();
+ return mapBluetoothCodecToAudioFormat(btCodecConfig.getCodecType());
+ }
+ return AudioSystem.AUDIO_FORMAT_DEFAULT;
+ }
+ }
+
/*
* A class just for packaging up a set of connection parameters.
*/
@@ -4751,14 +4815,16 @@ public class AudioService extends IAudioService.Stub
return delay;
}
- public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)
+ public int setBluetoothA2dpDeviceConnectionState(
+ BluetoothDevice device, int state, int profile)
{
return setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- device, state, profile, false /* suppressNoisyIntent */, -1 /* a2dpVolume */);
+ device, state, profile, false /* suppressNoisyIntent */,
+ -1 /* a2dpVolume */);
}
public int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(BluetoothDevice device,
- int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)
+ int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)
{
mDeviceLogger.log((new AudioEventLogger.StringEvent(
"setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent state=" + state
@@ -4771,7 +4837,8 @@ public class AudioService extends IAudioService.Stub
return 0;
}
return setBluetoothA2dpDeviceConnectionStateInt(
- device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume);
+ device, state, profile, suppressNoisyIntent,
+ AudioSystem.DEVICE_NONE, a2dpVolume);
}
public int setBluetoothA2dpDeviceConnectionStateInt(
@@ -4791,18 +4858,20 @@ public class AudioService extends IAudioService.Stub
delay = 0;
}
+ int a2dpCodec = getA2dpCodec(device);
+
if (DEBUG_DEVICES) {
Log.d(TAG, "setBluetoothA2dpDeviceConnectionStateInt device: " + device
- + " state: " + state + " delay(ms): " + delay
- + " suppressNoisyIntent: " + suppressNoisyIntent);
+ + " state: " + state + " delay(ms): " + delay + "codec:" + a2dpCodec
+ + " suppressNoisyIntent: " + suppressNoisyIntent);
}
queueMsgUnderWakeLock(mAudioHandler,
(profile == BluetoothProfile.A2DP ?
MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
state,
- a2dpVolume,
- device,
+ 0, /* arg2 unused */
+ new BluetoothA2dpDeviceInfo(device, a2dpVolume, a2dpCodec),
delay);
}
return delay;
@@ -4811,11 +4880,12 @@ public class AudioService extends IAudioService.Stub
public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device)
{
synchronized (mConnectedDevices) {
+ int a2dpCodec = getA2dpCodec(device);
queueMsgUnderWakeLock(mAudioHandler,
MSG_A2DP_DEVICE_CONFIG_CHANGE,
0 /* arg1 unused */,
- 0 /* arg1 unused */,
- device,
+ 0 /* arg2 unused */,
+ new BluetoothA2dpDeviceInfo(device, -1, a2dpCodec),
0 /* delay */);
}
}
@@ -5697,7 +5767,7 @@ public class AudioService extends IAudioService.Stub
case MSG_BTA2DP_DOCK_TIMEOUT:
// msg.obj == address of BTA2DP device
synchronized (mConnectedDevices) {
- makeA2dpDeviceUnavailableNow( (String) msg.obj );
+ makeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1);
}
mAudioEventWakeLock.release();
break;
@@ -5722,12 +5792,12 @@ public class AudioService extends IAudioService.Stub
break;
case MSG_SET_A2DP_SRC_CONNECTION_STATE:
- onSetA2dpSourceConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ onSetA2dpSourceConnectionState((BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
mAudioEventWakeLock.release();
break;
case MSG_SET_A2DP_SINK_CONNECTION_STATE:
- onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1, msg.arg2);
+ onSetA2dpSinkConnectionState((BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
mAudioEventWakeLock.release();
break;
@@ -5737,7 +5807,7 @@ public class AudioService extends IAudioService.Stub
break;
case MSG_A2DP_DEVICE_CONFIG_CHANGE:
- onBluetoothA2dpDeviceConfigChange((BluetoothDevice)msg.obj);
+ onBluetoothA2dpDeviceConfigChange((BluetoothA2dpDeviceInfo) msg.obj);
mAudioEventWakeLock.release();
break;
@@ -5911,19 +5981,20 @@ public class AudioService extends IAudioService.Stub
}
// must be called synchronized on mConnectedDevices
- private void makeA2dpDeviceAvailable(String address, String name, String eventSource) {
+ private void makeA2dpDeviceAvailable(
+ String address, String name, String eventSource, int a2dpCodec) {
// enable A2DP before notifying A2DP connection to avoid unnecessary processing in
// audio policy manager
VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
setBluetoothA2dpOnInt(true, eventSource);
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, name);
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, name, a2dpCodec);
// Reset A2DP suspend state each time a new sink is connected
AudioSystem.setParameters("A2dpSuspended=false");
mConnectedDevices.put(
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address),
new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name,
- address));
+ address, a2dpCodec));
sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, null, 0);
setCurrentAudioRouteNameIfPossible(name);
@@ -5936,7 +6007,7 @@ public class AudioService extends IAudioService.Stub
}
// must be called synchronized on mConnectedDevices
- private void makeA2dpDeviceUnavailableNow(String address) {
+ private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
if (address == null) {
return;
}
@@ -5944,7 +6015,7 @@ public class AudioService extends IAudioService.Stub
mAvrcpAbsVolSupported = false;
}
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "");
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "", a2dpCodec);
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
// Remove A2DP routes as well
@@ -5959,32 +6030,38 @@ public class AudioService extends IAudioService.Stub
// prevent any activity on the A2DP audio output to avoid unwanted
// reconnection of the sink.
AudioSystem.setParameters("A2dpSuspended=true");
+ // Retrieve deviceSpec before removing device
+ String deviceKey = makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
+ DeviceListSpec deviceSpec = mConnectedDevices.get(deviceKey);
+ int a2dpCodec = deviceSpec != null ? deviceSpec.mDeviceCodecFormat :
+ AudioSystem.AUDIO_FORMAT_DEFAULT;
// the device will be made unavailable later, so consider it disconnected right away
- mConnectedDevices.remove(
- makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
+ mConnectedDevices.remove(deviceKey);
// send the delayed message to make the device unavailable later
queueMsgUnderWakeLock(mAudioHandler,
- MSG_BTA2DP_DOCK_TIMEOUT,
- 0,
- 0,
- address,
- delayMs);
+ MSG_BTA2DP_DOCK_TIMEOUT,
+ a2dpCodec,
+ 0,
+ address,
+ delayMs);
}
// must be called synchronized on mConnectedDevices
private void makeA2dpSrcAvailable(String address) {
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, "");
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, "",
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.put(
makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, "",
- address));
+ address, AudioSystem.AUDIO_FORMAT_DEFAULT));
}
// must be called synchronized on mConnectedDevices
private void makeA2dpSrcUnavailable(String address) {
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "");
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "",
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
}
@@ -6008,11 +6085,12 @@ public class AudioService extends IAudioService.Stub
setHearingAidVolume(index, AudioSystem.STREAM_MUSIC);
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_HEARING_AID,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, name);
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, name,
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.put(
makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address),
new DeviceListSpec(AudioSystem.DEVICE_OUT_HEARING_AID, name,
- address));
+ address, AudioSystem.AUDIO_FORMAT_DEFAULT));
sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
AudioSystem.DEVICE_OUT_HEARING_AID, 0, null, 0);
sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
@@ -6024,7 +6102,8 @@ public class AudioService extends IAudioService.Stub
// must be called synchronized on mConnectedDevices
private void makeHearingAidDeviceUnavailable(String address) {
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_HEARING_AID,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "");
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "",
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address));
// Remove Hearing Aid routes as well
@@ -6041,15 +6120,23 @@ public class AudioService extends IAudioService.Stub
return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
}
- private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state, int a2dpVolume)
+ private void onSetA2dpSinkConnectionState(BluetoothA2dpDeviceInfo btInfo, int state)
{
- if (DEBUG_DEVICES) {
- Log.d(TAG, "onSetA2dpSinkConnectionState btDevice= " + btDevice+" state= " + state
- + " is dock: "+btDevice.isBluetoothDock());
+ if (btInfo == null) {
+ return;
}
+
+ BluetoothDevice btDevice = btInfo.getBtDevice();
+ int a2dpVolume = btInfo.getVolume();
+ int a2dpCodec = btInfo.getCodec();
+
if (btDevice == null) {
return;
}
+ if (DEBUG_DEVICES) {
+ Log.d(TAG, "onSetA2dpSinkConnectionState btDevice= " + btDevice + " state= " + state
+ + " is dock: " + btDevice.isBluetoothDock());
+ }
String address = btDevice.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
address = "";
@@ -6071,7 +6158,7 @@ public class AudioService extends IAudioService.Stub
// the next time isConnected is evaluated, it will be false for the dock
}
} else {
- makeA2dpDeviceUnavailableNow(address);
+ makeA2dpDeviceUnavailableNow(address, deviceSpec.mDeviceCodecFormat);
}
} else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
if (btDevice.isBluetoothDock()) {
@@ -6083,7 +6170,8 @@ public class AudioService extends IAudioService.Stub
// a dock: cancel the dock timeout, and make the dock unavailable now
if (hasScheduledA2dpDockTimeout() && mDockAddress != null) {
cancelA2dpDeviceTimeout();
- makeA2dpDeviceUnavailableNow(mDockAddress);
+ makeA2dpDeviceUnavailableNow(mDockAddress,
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
}
}
if (a2dpVolume != -1) {
@@ -6095,13 +6183,18 @@ public class AudioService extends IAudioService.Stub
setDeviceVolume(streamState, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
}
makeA2dpDeviceAvailable(address, btDevice.getName(),
- "onSetA2dpSinkConnectionState");
+ "onSetA2dpSinkConnectionState", a2dpCodec);
}
}
}
- private void onSetA2dpSourceConnectionState(BluetoothDevice btDevice, int state)
+ private void onSetA2dpSourceConnectionState(BluetoothA2dpDeviceInfo btInfo, int state)
{
+ if (btInfo == null) {
+ return;
+ }
+ BluetoothDevice btDevice = btInfo.getBtDevice();
+
if (DEBUG_VOL) {
Log.d(TAG, "onSetA2dpSourceConnectionState btDevice=" + btDevice + " state=" + state);
}
@@ -6176,8 +6269,14 @@ public class AudioService extends IAudioService.Stub
return false;
}
- private void onBluetoothA2dpDeviceConfigChange(BluetoothDevice btDevice)
+ private void onBluetoothA2dpDeviceConfigChange(BluetoothA2dpDeviceInfo btInfo)
{
+ if (btInfo == null) {
+ return;
+ }
+ BluetoothDevice btDevice = btInfo.getBtDevice();
+ int a2dpCodec = btInfo.getCodec();
+
if (DEBUG_DEVICES) {
Log.d(TAG, "onBluetoothA2dpDeviceConfigChange btDevice=" + btDevice);
}
@@ -6200,17 +6299,27 @@ public class AudioService extends IAudioService.Stub
}
final String key = makeDeviceListKey(device, address);
final DeviceListSpec deviceSpec = mConnectedDevices.get(key);
- if (deviceSpec != null) {
- // Device is connected
- int musicDevice = getDeviceForStream(AudioSystem.STREAM_MUSIC);
- if (AudioSystem.handleDeviceConfigChange(device, address,
- btDevice.getName()) != AudioSystem.AUDIO_STATUS_OK) {
- // force A2DP device disconnection in case of error so that AudioService state is
- // consistent with audio policy manager state
- setBluetoothA2dpDeviceConnectionStateInt(
- btDevice, BluetoothA2dp.STATE_DISCONNECTED, BluetoothProfile.A2DP,
- false /* suppressNoisyIntent */, musicDevice, -1 /* a2dpVolume */);
- }
+ if (deviceSpec == null) {
+ return;
+ }
+ // Device is connected
+ if (deviceSpec.mDeviceCodecFormat != a2dpCodec) {
+ deviceSpec.mDeviceCodecFormat = a2dpCodec;
+ mConnectedDevices.replace(key, deviceSpec);
+ }
+ if (DEBUG_DEVICES) {
+ Log.d(TAG, "onBluetoothA2dpDeviceConfigChange: codec="
+ + deviceSpec.mDeviceCodecFormat);
+ }
+ if (AudioSystem.handleDeviceConfigChange(device, address,
+ btDevice.getName(), deviceSpec.mDeviceCodecFormat)
+ != AudioSystem.AUDIO_STATUS_OK) {
+ int musicDevice = getDeviceForStream(AudioSystem.STREAM_MUSIC);
+ // force A2DP device disconnection in case of error so that AudioService state is
+ // consistent with audio policy manager state
+ setBluetoothA2dpDeviceConnectionStateInt(
+ btDevice, BluetoothA2dp.STATE_DISCONNECTED, BluetoothProfile.A2DP,
+ false /* suppressNoisyIntent */, musicDevice, -1 /* a2dpVolume */);
}
}
}
@@ -6243,19 +6352,22 @@ public class AudioService extends IAudioService.Stub
}
if (connect && !isConnected) {
final int res = AudioSystem.setDeviceConnectionState(device,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName);
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName,
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
if (res != AudioSystem.AUDIO_STATUS_OK) {
Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device) +
" due to command error " + res );
return false;
}
- mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address));
+ mConnectedDevices.put(deviceKey, new DeviceListSpec(device,
+ deviceName, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
device, 0, null, 0);
return true;
} else if (!connect && isConnected) {
AudioSystem.setDeviceConnectionState(device,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName);
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName,
+ AudioSystem.AUDIO_FORMAT_DEFAULT);
// always remove even if disconnection failed
mConnectedDevices.remove(deviceKey);
return true;