Added some hacks to ensure bluetooth route is used

This commit is contained in:
Sylvain Berfini 2014-04-02 09:46:11 +02:00
parent e4843aa561
commit 4f5e76c4dc
2 changed files with 47 additions and 30 deletions

View file

@ -57,6 +57,7 @@ public class BluetoothManager extends BroadcastReceiver {
private BluetoothDevice mBluetoothDevice; private BluetoothDevice mBluetoothDevice;
private BluetoothProfile.ServiceListener mProfileListener; private BluetoothProfile.ServiceListener mProfileListener;
private boolean isBluetoothConnected; private boolean isBluetoothConnected;
private boolean isScoConnected;
public static BluetoothManager getInstance() { public static BluetoothManager getInstance() {
if (instance == null) { if (instance == null) {
@ -125,10 +126,6 @@ public class BluetoothManager extends BroadcastReceiver {
} }
public boolean routeAudioToBluetooth() { public boolean routeAudioToBluetooth() {
return routeAudioToBluetooth(false);
}
private boolean routeAudioToBluetooth(boolean isRetry) {
if (mBluetoothAdapter == null) { if (mBluetoothAdapter == null) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
} }
@ -136,27 +133,39 @@ public class BluetoothManager extends BroadcastReceiver {
if (mBluetoothAdapter.isEnabled() && mAudioManager.isBluetoothScoAvailableOffCall()) { if (mBluetoothAdapter.isEnabled() && mAudioManager.isBluetoothScoAvailableOffCall()) {
if (isBluetoothHeadsetAvailable()) { if (isBluetoothHeadsetAvailable()) {
if (mAudioManager != null && !mAudioManager.isBluetoothScoOn()) { if (mAudioManager != null && !mAudioManager.isBluetoothScoOn()) {
Log.d("Bluetooth sco off, let's start it");
mAudioManager.setBluetoothScoOn(true); mAudioManager.setBluetoothScoOn(true);
mAudioManager.startBluetoothSco(); mAudioManager.startBluetoothSco();
} }
} else {
return false;
} }
boolean ok = mBluetoothHeadset != null && mBluetoothHeadset.isAudioConnected(mBluetoothDevice); // Hack to ensure bluetooth sco is really running
if (!ok && !isRetry) { boolean ok = isUsingBluetoothAudioRoute();
Log.w("Routing audio to bluetooth headset failed, retry...."); int retries = 0;
while (!ok && retries < 5) {
retries++;
try { try {
Thread.sleep(100); Thread.sleep(200);
} catch (InterruptedException e) {} } catch (InterruptedException e) {}
return routeAudioToBluetooth(true);
} else if (isRetry) { if (mAudioManager != null) {
if (ok) { mAudioManager.setBluetoothScoOn(true);
Log.d("Retry worked, audio is routed to bluetooth headset"); mAudioManager.startBluetoothSco();
}
ok = isUsingBluetoothAudioRoute();
}
if (ok) {
if (retries > 0) {
Log.d("Bluetooth route ok after " + retries + " retries");
} else { } else {
Log.e("Retry not worked, audio isn't routed to bluetooth headset..."); Log.d("Bluetooth route ok");
disableBluetoothSCO();
} }
} else { } else {
Log.d("Routing audio to bluetooth headset worked at first try"); Log.d("Bluetooth still not ok...");
} }
return ok; return ok;
@ -166,7 +175,7 @@ public class BluetoothManager extends BroadcastReceiver {
} }
public boolean isUsingBluetoothAudioRoute() { public boolean isUsingBluetoothAudioRoute() {
return mBluetoothHeadset != null && mBluetoothHeadset.isAudioConnected(mBluetoothDevice); return mBluetoothHeadset != null && mBluetoothHeadset.isAudioConnected(mBluetoothDevice) && isScoConnected;
} }
public boolean isBluetoothHeadsetAvailable() { public boolean isBluetoothHeadsetAvailable() {
@ -198,9 +207,19 @@ public class BluetoothManager extends BroadcastReceiver {
if (mAudioManager != null && mAudioManager.isBluetoothScoOn()) { if (mAudioManager != null && mAudioManager.isBluetoothScoOn()) {
mAudioManager.stopBluetoothSco(); mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false); mAudioManager.setBluetoothScoOn(false);
Log.w("Hack: stopping bluetooth sco again since first time won't have succedded");
mAudioManager.stopBluetoothSco(); // Hack to ensure bluetooth sco is really stopped
mAudioManager.setBluetoothScoOn(false); int retries = 0;
while (isScoConnected && retries < 10) {
retries++;
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
mAudioManager.stopBluetoothSco();
mAudioManager.setBluetoothScoOn(false);
}
Log.w("Bluetooth sco disconnected!"); Log.w("Bluetooth sco disconnected!");
} }
} }
@ -247,11 +266,11 @@ public class BluetoothManager extends BroadcastReceiver {
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
Log.d("Bluetooth sco state => connected"); Log.d("Bluetooth sco state => connected");
LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH); LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
//isUsingBluetoothAudioRoute = true; isScoConnected = true;
} else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) { } else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
Log.d("Bluetooth sco state => disconnected"); Log.d("Bluetooth sco state => disconnected");
LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER); LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER);
//isUsingBluetoothAudioRoute = false; isScoConnected = false;
} else { } else {
Log.d("Bluetooth sco state => " + state); Log.d("Bluetooth sco state => " + state);
} }

View file

@ -910,15 +910,13 @@ public class LinphoneManager implements LinphoneCoreListener {
if (state == State.StreamsRunning) { if (state == State.StreamsRunning) {
if (BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) { if (BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) {
BluetoothManager.getInstance().routeAudioToBluetooth(); BluetoothManager.getInstance().routeAudioToBluetooth();
// Hack for Android 4.2.2: we have to retry later, the first call will fail // Hack to ensure the bluetooth route is really used
if (Build.VERSION.SDK_INT == 17) { mHandler.postDelayed(new Runnable() {
mHandler.postDelayed(new Runnable() { @Override
@Override public void run() {
public void run() { BluetoothManager.getInstance().routeAudioToBluetooth();
BluetoothManager.getInstance().routeAudioToBluetooth(); }
} }, 500);
}, 500);
}
} }
if (mIncallWakeLock == null) { if (mIncallWakeLock == null) {