diff options
| author | Eric Laurent <elaurent@google.com> | 2009-10-16 09:16:26 -0700 |
|---|---|---|
| committer | Eric Laurent <elaurent@google.com> | 2009-10-26 09:17:10 -0700 |
| commit | a47d153647d8750b667942ad80e7b905ea98c68b (patch) | |
| tree | 47a4f5bdbef1cfb67fe5aff55b5054dcb8242f5e /core/java | |
| parent | 6897e36b894b2a10fd8b2e3af6587b5f789fde72 (diff) | |
| download | frameworks_base-a47d153647d8750b667942ad80e7b905ea98c68b.zip frameworks_base-a47d153647d8750b667942ad80e7b905ea98c68b.tar.gz frameworks_base-a47d153647d8750b667942ad80e7b905ea98c68b.tar.bz2 | |
do not merge - Fix for issue 2184627 cherry picked from eclair-mr2
Bluetooth A2DP suspend-resume improvements.
This change will reduce the occurence rate of A2DP sink suspend resume failures observed in issues 2184627, 2181005 and possibly 2189628.
More robust suspend/resume logic.
Use only the suspend request to audio hardware to avoid having two concurent suspend resume control paths.
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/server/BluetoothA2dpService.java | 95 |
1 files changed, 31 insertions, 64 deletions
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java index 9a2d6d9..ec3b2ff 100644 --- a/core/java/android/server/BluetoothA2dpService.java +++ b/core/java/android/server/BluetoothA2dpService.java @@ -72,8 +72,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { private final AudioManager mAudioManager; private final BluetoothService mBluetoothService; private final BluetoothAdapter mAdapter; - private boolean mSuspending; - private boolean mResuming; + private int mTargetA2dpState; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -151,8 +150,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { if (mBluetoothService.isEnabled()) onBluetoothEnable(); - mSuspending = false; - mResuming = false; + mTargetA2dpState = -1; } @Override @@ -341,10 +339,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { public synchronized boolean suspendSink(BluetoothDevice device) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (DBG) log("suspendSink(" + device + "), mSuspending: "+mSuspending+", mResuming: "+mResuming); - if (mSuspending) { - return true; - } + if (DBG) log("suspendSink(" + device + "), mTargetA2dpState: "+mTargetA2dpState); if (device == null || mAudioDevices == null) { return false; } @@ -353,28 +348,15 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { if (path == null || state == null) { return false; } - switch (state.intValue()) { - case BluetoothA2dp.STATE_CONNECTED: - if (mResuming) { - mSuspending = true; - } - return true; - case BluetoothA2dp.STATE_PLAYING: - mAudioManager.setParameters("A2dpSuspended=true"); - mSuspending = suspendSinkNative(path); - return mSuspending; - default: - return false; - } + + mTargetA2dpState = BluetoothA2dp.STATE_CONNECTED; + return checkSinkSuspendState(state.intValue()); } public synchronized boolean resumeSink(BluetoothDevice device) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); - if (DBG) log("resumeSink(" + device + "), mResuming: "+mResuming+", mSuspending: "+mSuspending); - if (mResuming) { - return true; - } + if (DBG) log("resumeSink(" + device + "), mTargetA2dpState: "+mTargetA2dpState); if (device == null || mAudioDevices == null) { return false; } @@ -383,19 +365,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { if (path == null || state == null) { return false; } - switch (state.intValue()) { - case BluetoothA2dp.STATE_PLAYING: - if (mSuspending) { - mResuming = true; - } - return true; - case BluetoothA2dp.STATE_CONNECTED: - mResuming = resumeSinkNative(path); - mAudioManager.setParameters("A2dpSuspended=false"); - return mResuming; - default: - return false; - } + mTargetA2dpState = BluetoothA2dp.STATE_PLAYING; + return checkSinkSuspendState(state.intValue()); } public synchronized BluetoothDevice[] getConnectedSinks() { @@ -458,10 +429,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } private void handleSinkStateChange(BluetoothDevice device, int prevState, int state) { - if (state == BluetoothA2dp.STATE_DISCONNECTED) { - mSuspending = false; - mResuming = false; - } if (state != prevState) { if (state == BluetoothA2dp.STATE_DISCONNECTED || state == BluetoothA2dp.STATE_DISCONNECTING) { @@ -477,28 +444,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } mAudioDevices.put(device, state); - if (state == BluetoothA2dp.STATE_CONNECTED && prevState == BluetoothA2dp.STATE_PLAYING) { - if (DBG) log("handleSinkStateChange() STATE_PLAYING -> STATE_CONNECTED: mSuspending: " - +mSuspending+", mResuming: "+mResuming); - if (mSuspending) { - mSuspending = false; - if (mResuming) { - mResuming = false; - resumeSink(device); - } - } - } - if (state == BluetoothA2dp.STATE_PLAYING && prevState == BluetoothA2dp.STATE_CONNECTED) { - if (DBG) log("handleSinkStateChange() STATE_CONNECTED -> STATE_PLAYING: mSuspending: " - +mSuspending+", mResuming: "+mResuming); - - if (mResuming) { - mResuming = false; - if (mSuspending) { - mSuspending = false; - suspendSink(device); - } - } + checkSinkSuspendState(state); + mTargetA2dpState = -1; + + if (state == BluetoothA2dp.STATE_CONNECTING) { + mAudioManager.setParameters("A2dpSuspended=false"); } Intent intent = new Intent(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); @@ -527,6 +477,23 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { return sinks; } + private boolean checkSinkSuspendState(int state) { + boolean result = true; + + if (state != mTargetA2dpState) { + if (state == BluetoothA2dp.STATE_PLAYING && + mTargetA2dpState == BluetoothA2dp.STATE_CONNECTED) { + mAudioManager.setParameters("A2dpSuspended=true"); + } else if (state == BluetoothA2dp.STATE_CONNECTED && + mTargetA2dpState == BluetoothA2dp.STATE_PLAYING) { + mAudioManager.setParameters("A2dpSuspended=false"); + } else { + result = false; + } + } + return result; + } + @Override protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mAudioDevices.isEmpty()) return; |
