Merge "AudioService: fix overlapping speakerphone + Bluetooth SCO routing requests" into rvc-qpr-dev
This commit is contained in:
@@ -224,12 +224,35 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
if (!addSpeakerphoneClient(cb, pid, on)) {
|
||||
return false;
|
||||
}
|
||||
if (on) {
|
||||
// Cancel BT SCO ON request by this same client: speakerphone and BT SCO routes
|
||||
// are mutually exclusive.
|
||||
// See symmetrical operation for startBluetoothScoForClient_Sync().
|
||||
mBtHelper.stopBluetoothScoForPid(pid);
|
||||
}
|
||||
final boolean wasOn = isSpeakerphoneOn();
|
||||
updateSpeakerphoneOn(eventSource);
|
||||
return (wasOn != isSpeakerphoneOn());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns speakerphone off for a given pid and update speakerphone state.
|
||||
* @param pid
|
||||
*/
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private void setSpeakerphoneOffForPid(int pid) {
|
||||
SpeakerphoneClient client = getSpeakerphoneClientForPid(pid);
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
client.unregisterDeathRecipient();
|
||||
mSpeakerphoneClients.remove(client);
|
||||
final String eventSource = new StringBuilder("setSpeakerphoneOffForPid(")
|
||||
.append(pid).append(")").toString();
|
||||
updateSpeakerphoneOn(eventSource);
|
||||
}
|
||||
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private void updateSpeakerphoneOn(String eventSource) {
|
||||
if (isSpeakerphoneOnRequested()) {
|
||||
@@ -488,6 +511,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
/*package*/ void startBluetoothScoForClient_Sync(IBinder cb, int scoAudioMode,
|
||||
@NonNull String eventSource) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
// Cancel speakerphone ON request by this same client: speakerphone and BT SCO routes
|
||||
// are mutually exclusive.
|
||||
// See symmetrical operation for setSpeakerphoneOn(true).
|
||||
setSpeakerphoneOffForPid(Binder.getCallingPid());
|
||||
mBtHelper.startBluetoothScoForClient(cb, scoAudioMode, eventSource);
|
||||
}
|
||||
}
|
||||
@@ -1381,6 +1408,16 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
return false;
|
||||
}
|
||||
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private SpeakerphoneClient getSpeakerphoneClientForPid(int pid) {
|
||||
for (SpeakerphoneClient cl : mSpeakerphoneClients) {
|
||||
if (cl.getPid() == pid) {
|
||||
return cl;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// List of clients requesting speakerPhone ON
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private final @NonNull ArrayList<SpeakerphoneClient> mSpeakerphoneClients =
|
||||
|
||||
@@ -432,19 +432,36 @@ public class BtHelper {
|
||||
// and this must be done on behalf of system server to make sure permissions are granted.
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
if (client != null) {
|
||||
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
|
||||
client.requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
|
||||
SCO_MODE_VIRTUAL_CALL);
|
||||
// If a disconnection is pending, the client will be removed whne clearAllScoClients()
|
||||
// is called form receiveBtEvent()
|
||||
if (mScoAudioState != SCO_STATE_DEACTIVATE_REQ
|
||||
&& mScoAudioState != SCO_STATE_DEACTIVATING) {
|
||||
client.remove(false /*stop */, true /*unregister*/);
|
||||
}
|
||||
stopAndRemoveClient(client, eventSource);
|
||||
}
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
|
||||
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
/*package*/ synchronized void stopBluetoothScoForPid(int pid) {
|
||||
ScoClient client = getScoClientForPid(pid);
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
final String eventSource = new StringBuilder("stopBluetoothScoForPid(")
|
||||
.append(pid).append(")").toString();
|
||||
stopAndRemoveClient(client, eventSource);
|
||||
}
|
||||
|
||||
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
// @GuardedBy("BtHelper.this")
|
||||
private void stopAndRemoveClient(ScoClient client, @NonNull String eventSource) {
|
||||
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
|
||||
client.requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
|
||||
SCO_MODE_VIRTUAL_CALL);
|
||||
// If a disconnection is pending, the client will be removed when clearAllScoClients()
|
||||
// is called form receiveBtEvent()
|
||||
if (mScoAudioState != SCO_STATE_DEACTIVATE_REQ
|
||||
&& mScoAudioState != SCO_STATE_DEACTIVATING) {
|
||||
client.remove(false /*stop */, true /*unregister*/);
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ synchronized void setHearingAidVolume(int index, int streamType) {
|
||||
if (mHearingAid == null) {
|
||||
@@ -974,6 +991,16 @@ public class BtHelper {
|
||||
return null;
|
||||
}
|
||||
|
||||
@GuardedBy("BtHelper.this")
|
||||
private ScoClient getScoClientForPid(int pid) {
|
||||
for (ScoClient cl : mScoClients) {
|
||||
if (cl.getPid() == pid) {
|
||||
return cl;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
|
||||
//@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
@GuardedBy("BtHelper.this")
|
||||
|
||||
Reference in New Issue
Block a user