Merge "audio: Send A2DP codec to AudioSystem on connection state change"
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index 80560f8..860de75 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -487,7 +487,8 @@
}
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 @@
}
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 @@
{"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 6b74479..774023f 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -140,6 +140,30 @@
}
}
+ /* 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);
@@ -865,12 +889,14 @@
*/
@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 d9fcf9e..2625c18 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.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 @@
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 @@
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 @@
spec.mDeviceType,
AudioSystem.DEVICE_STATE_AVAILABLE,
spec.mDeviceAddress,
- spec.mDeviceName);
+ spec.mDeviceName,
+ spec.mDeviceCodecFormat);
}
}
// Restore call state
@@ -3906,8 +3959,8 @@
queueMsgUnderWakeLock(mAudioHandler,
MSG_SET_A2DP_SINK_CONNECTION_STATE,
state,
- -1,
- btDevice,
+ 0 /* arg2 unused */,
+ new BluetoothA2dpDeviceInfo(btDevice),
delay);
}
}
@@ -3924,7 +3977,7 @@
MSG_SET_A2DP_SRC_CONNECTION_STATE,
state,
0 /* arg2 unused */,
- btDevice,
+ new BluetoothA2dpDeviceInfo(btDevice),
0 /* delay */);
}
}
@@ -4689,6 +4742,17 @@
}
}
+ 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.
*/
@@ -4753,14 +4817,16 @@
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
@@ -4773,7 +4839,8 @@
return 0;
}
return setBluetoothA2dpDeviceConnectionStateInt(
- device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume);
+ device, state, profile, suppressNoisyIntent,
+ AudioSystem.DEVICE_NONE, a2dpVolume);
}
public int setBluetoothA2dpDeviceConnectionStateInt(
@@ -4793,18 +4860,20 @@
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;
@@ -4813,11 +4882,12 @@
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 */);
}
}
@@ -5699,7 +5769,7 @@
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;
@@ -5724,12 +5794,12 @@
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;
@@ -5739,7 +5809,7 @@
break;
case MSG_A2DP_DEVICE_CONFIG_CHANGE:
- onBluetoothA2dpDeviceConfigChange((BluetoothDevice)msg.obj);
+ onBluetoothA2dpDeviceConfigChange((BluetoothA2dpDeviceInfo) msg.obj);
mAudioEventWakeLock.release();
break;
@@ -5913,19 +5983,20 @@
}
// 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);
@@ -5938,7 +6009,7 @@
}
// must be called synchronized on mConnectedDevices
- private void makeA2dpDeviceUnavailableNow(String address) {
+ private void makeA2dpDeviceUnavailableNow(String address, int a2dpCodec) {
if (address == null) {
return;
}
@@ -5946,7 +6017,7 @@
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
@@ -5961,32 +6032,38 @@
// 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));
}
@@ -6010,11 +6087,12 @@
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,
@@ -6026,7 +6104,8 @@
// 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
@@ -6043,15 +6122,23 @@
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 = "";
@@ -6073,7 +6160,7 @@
// 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()) {
@@ -6085,7 +6172,8 @@
// 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) {
@@ -6097,13 +6185,18 @@
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);
}
@@ -6178,8 +6271,14 @@
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);
}
@@ -6202,17 +6301,27 @@
}
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 */);
}
}
}
@@ -6245,19 +6354,22 @@
}
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;