Skip to content

Commit d7454be

Browse files
author
Eric Laurent
committed
Issue 5044873: Pb with BT SCO AudioManager API
Do not identify the SCO connection client by the binder interface passed when starting the connection as this binder changes if the AudioManager proxy changes. Use the client PID instead. This solves an issue with gTalk starting a SCO connection from one AudioManager proxy and then changing audio mode from another thus terminating the previously started SCO connection. Change-Id: Ia3067fecc551fc15df3bf75ce0c43d181859e4f0
1 parent cb18db8 commit d7454be

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

media/java/android/media/AudioService.java

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -773,20 +773,20 @@ private class SetModeDeathHandler implements IBinder.DeathRecipient {
773773
}
774774

775775
public void binderDied() {
776-
IBinder newModeOwner = null;
776+
int newModeOwnerPid = 0;
777777
synchronized(mSetModeDeathHandlers) {
778778
Log.w(TAG, "setMode() client died");
779779
int index = mSetModeDeathHandlers.indexOf(this);
780780
if (index < 0) {
781781
Log.w(TAG, "unregistered setMode() client died");
782782
} else {
783-
newModeOwner = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid);
783+
newModeOwnerPid = setModeInt(AudioSystem.MODE_NORMAL, mCb, mPid);
784784
}
785785
}
786786
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
787787
// SCO connections not started by the application changing the mode
788-
if (newModeOwner != null) {
789-
disconnectBluetoothSco(newModeOwner);
788+
if (newModeOwnerPid != 0) {
789+
disconnectBluetoothSco(newModeOwnerPid);
790790
}
791791
}
792792

@@ -817,28 +817,28 @@ public void setMode(int mode, IBinder cb) {
817817
return;
818818
}
819819

820-
IBinder newModeOwner = null;
820+
int newModeOwnerPid = 0;
821821
synchronized(mSetModeDeathHandlers) {
822822
if (mode == AudioSystem.MODE_CURRENT) {
823823
mode = mMode;
824824
}
825-
newModeOwner = setModeInt(mode, cb, Binder.getCallingPid());
825+
newModeOwnerPid = setModeInt(mode, cb, Binder.getCallingPid());
826826
}
827827
// when entering RINGTONE, IN_CALL or IN_COMMUNICATION mode, clear all
828828
// SCO connections not started by the application changing the mode
829-
if (newModeOwner != null) {
830-
disconnectBluetoothSco(newModeOwner);
829+
if (newModeOwnerPid != 0) {
830+
disconnectBluetoothSco(newModeOwnerPid);
831831
}
832832
}
833833

834834
// must be called synchronized on mSetModeDeathHandlers
835-
// setModeInt() returns a non null IBInder if the audio mode was successfully set to
835+
// setModeInt() returns a valid PID if the audio mode was successfully set to
836836
// any mode other than NORMAL.
837-
IBinder setModeInt(int mode, IBinder cb, int pid) {
838-
IBinder newModeOwner = null;
837+
int setModeInt(int mode, IBinder cb, int pid) {
838+
int newModeOwnerPid = 0;
839839
if (cb == null) {
840840
Log.e(TAG, "setModeInt() called with null binder");
841-
return newModeOwner;
841+
return newModeOwnerPid;
842842
}
843843

844844
SetModeDeathHandler hdlr = null;
@@ -901,13 +901,17 @@ IBinder setModeInt(int mode, IBinder cb, int pid) {
901901

902902
if (status == AudioSystem.AUDIO_STATUS_OK) {
903903
if (mode != AudioSystem.MODE_NORMAL) {
904-
newModeOwner = cb;
904+
if (mSetModeDeathHandlers.isEmpty()) {
905+
Log.e(TAG, "setMode() different from MODE_NORMAL with empty mode client stack");
906+
} else {
907+
newModeOwnerPid = mSetModeDeathHandlers.get(0).getPid();
908+
}
905909
}
906910
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
907911
int index = mStreamStates[STREAM_VOLUME_ALIAS[streamType]].mIndex;
908912
setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, true, false);
909913
}
910-
return newModeOwner;
914+
return newModeOwnerPid;
911915
}
912916

913917
/** pre-condition: oldMode != newMode */
@@ -1351,6 +1355,10 @@ public IBinder getBinder() {
13511355
return mCb;
13521356
}
13531357

1358+
public int getPid() {
1359+
return mCreatorPid;
1360+
}
1361+
13541362
public int totalCount() {
13551363
synchronized(mScoClients) {
13561364
int count = 0;
@@ -1445,13 +1453,13 @@ private ScoClient getScoClient(IBinder cb, boolean create) {
14451453
}
14461454
}
14471455

1448-
public void clearAllScoClients(IBinder exceptBinder, boolean stopSco) {
1456+
public void clearAllScoClients(int exceptPid, boolean stopSco) {
14491457
synchronized(mScoClients) {
14501458
ScoClient savedClient = null;
14511459
int size = mScoClients.size();
14521460
for (int i = 0; i < size; i++) {
14531461
ScoClient cl = mScoClients.get(i);
1454-
if (cl.getBinder() != exceptBinder) {
1462+
if (cl.getPid() != exceptPid) {
14551463
cl.clearCount(stopSco);
14561464
} else {
14571465
savedClient = cl;
@@ -1480,7 +1488,7 @@ private boolean getBluetoothHeadset() {
14801488
return result;
14811489
}
14821490

1483-
private void disconnectBluetoothSco(IBinder exceptBinder) {
1491+
private void disconnectBluetoothSco(int exceptPid) {
14841492
synchronized(mScoClients) {
14851493
checkScoAudioState();
14861494
if (mScoAudioState == SCO_STATE_ACTIVE_EXTERNAL ||
@@ -1498,14 +1506,14 @@ private void disconnectBluetoothSco(IBinder exceptBinder) {
14981506
}
14991507
}
15001508
} else {
1501-
clearAllScoClients(exceptBinder, true);
1509+
clearAllScoClients(exceptPid, true);
15021510
}
15031511
}
15041512
}
15051513

15061514
private void resetBluetoothSco() {
15071515
synchronized(mScoClients) {
1508-
clearAllScoClients(null, false);
1516+
clearAllScoClients(0, false);
15091517
mScoAudioState = SCO_STATE_INACTIVE;
15101518
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
15111519
}
@@ -2509,7 +2517,7 @@ public void onReceive(Context context, Intent intent) {
25092517
case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
25102518
state = AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
25112519
mScoAudioState = SCO_STATE_INACTIVE;
2512-
clearAllScoClients(null, false);
2520+
clearAllScoClients(0, false);
25132521
break;
25142522
case BluetoothHeadset.STATE_AUDIO_CONNECTING:
25152523
if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL &&

0 commit comments

Comments
 (0)