Merge "audioservice: fix not able to disconnect VoIP call" into rvc-dev
This commit is contained in:
@@ -324,7 +324,7 @@ import java.io.PrintWriter;
|
||||
}
|
||||
|
||||
/*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
|
||||
//Log.i(TAG, "setBluetoothScoOnInt: " + on + " " + eventSource);
|
||||
//Log.i(TAG, "setBluetoothScoOn: " + on + " " + eventSource);
|
||||
synchronized (mDeviceStateLock) {
|
||||
if (on) {
|
||||
// do not accept SCO ON if SCO audio is not connected
|
||||
|
||||
@@ -58,6 +58,7 @@ public class BtHelper {
|
||||
}
|
||||
|
||||
// List of clients having issued a SCO start request
|
||||
@GuardedBy("BtHelper.this")
|
||||
private final @NonNull ArrayList<ScoClient> mScoClients = new ArrayList<ScoClient>();
|
||||
|
||||
// BluetoothHeadset API to control SCO connection
|
||||
@@ -356,9 +357,8 @@ public class BtHelper {
|
||||
// client is created.
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
eventSource += " client count before=" + client.getCount();
|
||||
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
|
||||
client.incCount(scoAudioMode);
|
||||
client.requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode);
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(TAG, "Null ScoClient", e);
|
||||
}
|
||||
@@ -375,9 +375,15 @@ 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) {
|
||||
eventSource += " client count before=" + client.getCount();
|
||||
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(eventSource));
|
||||
client.decCount();
|
||||
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*/);
|
||||
}
|
||||
}
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -657,25 +663,33 @@ public class BtHelper {
|
||||
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
/*package*/ synchronized void scoClientDied(Object obj) {
|
||||
final ScoClient client = (ScoClient) obj;
|
||||
client.remove(true /*stop*/, false /*unregister*/);
|
||||
Log.w(TAG, "SCO client died");
|
||||
int index = mScoClients.indexOf(client);
|
||||
if (index < 0) {
|
||||
Log.w(TAG, "unregistered SCO client died");
|
||||
} else {
|
||||
client.clearCount(true);
|
||||
mScoClients.remove(client);
|
||||
}
|
||||
}
|
||||
|
||||
private class ScoClient implements IBinder.DeathRecipient {
|
||||
private IBinder mCb; // To be notified of client's death
|
||||
private int mCreatorPid;
|
||||
private int mStartcount; // number of SCO connections started by this client
|
||||
|
||||
ScoClient(IBinder cb) {
|
||||
mCb = cb;
|
||||
mCreatorPid = Binder.getCallingPid();
|
||||
mStartcount = 0;
|
||||
}
|
||||
|
||||
public void registerDeathRecipient() {
|
||||
try {
|
||||
mCb.linkToDeath(this, 0);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "ScoClient could not link to " + mCb + " binder death");
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterDeathRecipient() {
|
||||
try {
|
||||
mCb.unlinkToDeath(this, 0);
|
||||
} catch (NoSuchElementException e) {
|
||||
Log.w(TAG, "ScoClient could not not unregistered to binder");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -685,70 +699,6 @@ public class BtHelper {
|
||||
mDeviceBroker.postScoClientDied(this);
|
||||
}
|
||||
|
||||
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
|
||||
// @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
@GuardedBy("BtHelper.this")
|
||||
void incCount(int scoAudioMode) {
|
||||
if (!requestScoState(BluetoothHeadset.STATE_AUDIO_CONNECTED, scoAudioMode)) {
|
||||
Log.e(TAG, "Request sco connected with scoAudioMode("
|
||||
+ scoAudioMode + ") failed");
|
||||
return;
|
||||
}
|
||||
if (mStartcount == 0) {
|
||||
try {
|
||||
mCb.linkToDeath(this, 0);
|
||||
} catch (RemoteException e) {
|
||||
// client has already died!
|
||||
Log.w(TAG, "ScoClient incCount() could not link to "
|
||||
+ mCb + " binder death");
|
||||
}
|
||||
}
|
||||
mStartcount++;
|
||||
}
|
||||
|
||||
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
|
||||
// @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
@GuardedBy("BtHelper.this")
|
||||
void decCount() {
|
||||
if (mStartcount == 0) {
|
||||
Log.w(TAG, "ScoClient.decCount() already 0");
|
||||
} else {
|
||||
mStartcount--;
|
||||
if (mStartcount == 0) {
|
||||
try {
|
||||
mCb.unlinkToDeath(this, 0);
|
||||
} catch (NoSuchElementException e) {
|
||||
Log.w(TAG, "decCount() going to 0 but not registered to binder");
|
||||
}
|
||||
}
|
||||
if (!requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0)) {
|
||||
Log.w(TAG, "Request sco disconnected with scoAudioMode(0) failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
|
||||
// @GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
@GuardedBy("BtHelper.this")
|
||||
void clearCount(boolean stopSco) {
|
||||
if (mStartcount != 0) {
|
||||
try {
|
||||
mCb.unlinkToDeath(this, 0);
|
||||
} catch (NoSuchElementException e) {
|
||||
Log.w(TAG, "clearCount() mStartcount: "
|
||||
+ mStartcount + " != 0 but not registered to binder");
|
||||
}
|
||||
}
|
||||
mStartcount = 0;
|
||||
if (stopSco) {
|
||||
requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int getCount() {
|
||||
return mStartcount;
|
||||
}
|
||||
|
||||
IBinder getBinder() {
|
||||
return mCb;
|
||||
}
|
||||
@@ -757,23 +707,14 @@ public class BtHelper {
|
||||
return mCreatorPid;
|
||||
}
|
||||
|
||||
private int totalCount() {
|
||||
int count = 0;
|
||||
for (ScoClient mScoClient : mScoClients) {
|
||||
count += mScoClient.getCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
|
||||
//@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
@GuardedBy("BtHelper.this")
|
||||
private boolean requestScoState(int state, int scoAudioMode) {
|
||||
checkScoAudioState();
|
||||
int clientCount = totalCount();
|
||||
if (clientCount != 0) {
|
||||
if (mScoClients.size() != 1) {
|
||||
Log.i(TAG, "requestScoState: state=" + state + ", scoAudioMode=" + scoAudioMode
|
||||
+ ", clientCount=" + clientCount);
|
||||
+ ", num SCO clients=" + mScoClients.size());
|
||||
return true;
|
||||
}
|
||||
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
|
||||
@@ -842,12 +783,14 @@ public class BtHelper {
|
||||
mScoAudioState = SCO_STATE_ACTIVE_INTERNAL;
|
||||
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
|
||||
break;
|
||||
case SCO_STATE_ACTIVE_INTERNAL:
|
||||
Log.w(TAG, "requestScoState: already in ACTIVE mode, simply return");
|
||||
break;
|
||||
default:
|
||||
Log.w(TAG, "requestScoState: failed to connect in state "
|
||||
+ mScoAudioState + ", scoAudioMode=" + scoAudioMode);
|
||||
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
|
||||
return false;
|
||||
|
||||
}
|
||||
} else if (state == BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
|
||||
switch (mScoAudioState) {
|
||||
@@ -893,6 +836,18 @@ public class BtHelper {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@GuardedBy("BtHelper.this")
|
||||
void remove(boolean stop, boolean unregister) {
|
||||
if (unregister) {
|
||||
unregisterDeathRecipient();
|
||||
}
|
||||
if (stop) {
|
||||
requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED,
|
||||
SCO_MODE_VIRTUAL_CALL);
|
||||
}
|
||||
mScoClients.remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------
|
||||
@@ -946,6 +901,7 @@ public class BtHelper {
|
||||
}
|
||||
|
||||
|
||||
@GuardedBy("BtHelper.this")
|
||||
private ScoClient getScoClient(IBinder cb, boolean create) {
|
||||
for (ScoClient existingClient : mScoClients) {
|
||||
if (existingClient.getBinder() == cb) {
|
||||
@@ -954,6 +910,7 @@ public class BtHelper {
|
||||
}
|
||||
if (create) {
|
||||
ScoClient newClient = new ScoClient(cb);
|
||||
newClient.registerDeathRecipient();
|
||||
mScoClients.add(newClient);
|
||||
return newClient;
|
||||
}
|
||||
@@ -964,18 +921,16 @@ public class BtHelper {
|
||||
//@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
@GuardedBy("BtHelper.this")
|
||||
private void clearAllScoClients(int exceptPid, boolean stopSco) {
|
||||
ScoClient savedClient = null;
|
||||
final ArrayList<ScoClient> clients = new ArrayList<ScoClient>();
|
||||
for (ScoClient cl : mScoClients) {
|
||||
if (cl.getPid() != exceptPid) {
|
||||
cl.clearCount(stopSco);
|
||||
} else {
|
||||
savedClient = cl;
|
||||
clients.add(cl);
|
||||
}
|
||||
}
|
||||
mScoClients.clear();
|
||||
if (savedClient != null) {
|
||||
mScoClients.add(savedClient);
|
||||
for (ScoClient cl : clients) {
|
||||
cl.remove(stopSco, true /*unregister*/);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean getBluetoothHeadset() {
|
||||
|
||||
Reference in New Issue
Block a user