Loading core/java/android/server/BluetoothA2dpService.java +52 −4 Original line number Diff line number Diff line Loading @@ -72,6 +72,8 @@ 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 final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -149,6 +151,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { if (mBluetoothService.isEnabled()) onBluetoothEnable(); mSuspending = false; mResuming = false; } @Override Loading Loading @@ -241,6 +245,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } } mAudioManager.setParameters(BLUETOOTH_ENABLED+"=true"); mAudioManager.setParameters("A2dpSuspended=false"); } private synchronized void onBluetoothDisable() { Loading Loading @@ -336,7 +341,10 @@ 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 + ")"); if (DBG) log("suspendSink(" + device + "), mSuspending: "+mSuspending+", mResuming: "+mResuming); if (mSuspending) { return true; } if (device == null || mAudioDevices == null) { return false; } Loading @@ -347,9 +355,14 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } switch (state.intValue()) { case BluetoothA2dp.STATE_CONNECTED: if (mResuming) { mSuspending = true; } return true; case BluetoothA2dp.STATE_PLAYING: return suspendSinkNative(path); mAudioManager.setParameters("A2dpSuspended=true"); mSuspending = suspendSinkNative(path); return mSuspending; default: return false; } Loading @@ -358,7 +371,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { public synchronized boolean resumeSink(BluetoothDevice device) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); if (DBG) log("resumeSink(" + device + ")"); if (DBG) log("resumeSink(" + device + "), mResuming: "+mResuming+", mSuspending: "+mSuspending); if (mResuming) { return true; } if (device == null || mAudioDevices == null) { return false; } Loading @@ -369,9 +385,14 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } switch (state.intValue()) { case BluetoothA2dp.STATE_PLAYING: if (mSuspending) { mResuming = true; } return true; case BluetoothA2dp.STATE_CONNECTED: return resumeSinkNative(path); mResuming = resumeSinkNative(path); mAudioManager.setParameters("A2dpSuspended=false"); return mResuming; default: return false; } Loading Loading @@ -437,6 +458,10 @@ 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) { Loading @@ -452,6 +477,29 @@ 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); } } } Intent intent = new Intent(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothA2dp.EXTRA_PREVIOUS_SINK_STATE, prevState); Loading libs/audioflinger/A2dpAudioInterface.cpp +30 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ #include <math.h> #define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #define LOG_TAG "A2dpAudioInterface" #include <utils/Log.h> #include <utils/String8.h> Loading @@ -40,7 +40,7 @@ namespace android { //} A2dpAudioInterface::A2dpAudioInterface(AudioHardwareInterface* hw) : mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true) mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true), mSuspended(false) { } Loading Loading @@ -78,6 +78,7 @@ AudioStreamOut* A2dpAudioInterface::openOutputStream( if ((err = out->set(devices, format, channels, sampleRate)) == NO_ERROR) { mOutput = out; mOutput->setBluetoothEnabled(mBluetoothEnabled); mOutput->setSuspended(mSuspended); } else { delete out; } Loading Loading @@ -142,6 +143,14 @@ status_t A2dpAudioInterface::setParameters(const String8& keyValuePairs) } param.remove(key); } key = String8("A2dpSuspended"); if (param.get(key, value) == NO_ERROR) { mSuspended = (value == "true"); if (mOutput) { mOutput->setSuspended(mSuspended); } param.remove(key); } if (param.size()) { status_t hwStatus = mHardwareInterface->setParameters(param.toString()); Loading @@ -166,6 +175,12 @@ String8 A2dpAudioInterface::getParameters(const String8& keys) a2dpParam.add(key, value); param.remove(key); } key = "A2dpSuspended"; if (param.get(key, value) == NO_ERROR) { value = mSuspended ? "true" : "false"; a2dpParam.add(key, value); param.remove(key); } String8 keyValuePairs = a2dpParam.toString(); Loading Loading @@ -204,7 +219,7 @@ A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() : mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL), // assume BT enabled to start, this is safe because its only the // enabled->disabled transition we are worried about mBluetoothEnabled(true), mDevice(0), mClosing(false) mBluetoothEnabled(true), mDevice(0), mClosing(false), mSuspended(false) { // use any address by default strcpy(mA2dpAddress, "00:00:00:00:00:00"); Loading Loading @@ -258,8 +273,10 @@ ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t size_t remaining = bytes; status_t status = -1; if (!mBluetoothEnabled || mClosing) { LOGW("A2dpAudioStreamOut::write(), but bluetooth disabled"); if (!mBluetoothEnabled || mClosing || mSuspended) { LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \ mBluetoothEnabled %d, mClosing %d, mSuspended %d", mBluetoothEnabled, mClosing, mSuspended); goto Error; } Loading Loading @@ -408,6 +425,14 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::setBluetoothEnabled(bool enable return NO_ERROR; } status_t A2dpAudioInterface::A2dpAudioStreamOut::setSuspended(bool onOff) { LOGV("setSuspended %d", onOff); mSuspended = onOff; standby(); return NO_ERROR; } status_t A2dpAudioInterface::A2dpAudioStreamOut::close() { Mutex::Autolock lock(mLock); Loading libs/audioflinger/A2dpAudioInterface.h +3 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ private: status_t close_l(); status_t setAddress(const char* address); status_t setBluetoothEnabled(bool enabled); status_t setSuspended(bool onOff); private: int mFd; Loading @@ -113,6 +114,7 @@ private: bool mBluetoothEnabled; uint32_t mDevice; bool mClosing; bool mSuspended; }; friend class A2dpAudioStreamOut; Loading @@ -121,6 +123,7 @@ private: AudioHardwareInterface *mHardwareInterface; char mA2dpAddress[20]; bool mBluetoothEnabled; bool mSuspended; }; Loading Loading
core/java/android/server/BluetoothA2dpService.java +52 −4 Original line number Diff line number Diff line Loading @@ -72,6 +72,8 @@ 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 final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override Loading Loading @@ -149,6 +151,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { if (mBluetoothService.isEnabled()) onBluetoothEnable(); mSuspending = false; mResuming = false; } @Override Loading Loading @@ -241,6 +245,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } } mAudioManager.setParameters(BLUETOOTH_ENABLED+"=true"); mAudioManager.setParameters("A2dpSuspended=false"); } private synchronized void onBluetoothDisable() { Loading Loading @@ -336,7 +341,10 @@ 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 + ")"); if (DBG) log("suspendSink(" + device + "), mSuspending: "+mSuspending+", mResuming: "+mResuming); if (mSuspending) { return true; } if (device == null || mAudioDevices == null) { return false; } Loading @@ -347,9 +355,14 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } switch (state.intValue()) { case BluetoothA2dp.STATE_CONNECTED: if (mResuming) { mSuspending = true; } return true; case BluetoothA2dp.STATE_PLAYING: return suspendSinkNative(path); mAudioManager.setParameters("A2dpSuspended=true"); mSuspending = suspendSinkNative(path); return mSuspending; default: return false; } Loading @@ -358,7 +371,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { public synchronized boolean resumeSink(BluetoothDevice device) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH_ADMIN permission"); if (DBG) log("resumeSink(" + device + ")"); if (DBG) log("resumeSink(" + device + "), mResuming: "+mResuming+", mSuspending: "+mSuspending); if (mResuming) { return true; } if (device == null || mAudioDevices == null) { return false; } Loading @@ -369,9 +385,14 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub { } switch (state.intValue()) { case BluetoothA2dp.STATE_PLAYING: if (mSuspending) { mResuming = true; } return true; case BluetoothA2dp.STATE_CONNECTED: return resumeSinkNative(path); mResuming = resumeSinkNative(path); mAudioManager.setParameters("A2dpSuspended=false"); return mResuming; default: return false; } Loading Loading @@ -437,6 +458,10 @@ 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) { Loading @@ -452,6 +477,29 @@ 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); } } } Intent intent = new Intent(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device); intent.putExtra(BluetoothA2dp.EXTRA_PREVIOUS_SINK_STATE, prevState); Loading
libs/audioflinger/A2dpAudioInterface.cpp +30 −5 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ #include <math.h> #define LOG_NDEBUG 0 //#define LOG_NDEBUG 0 #define LOG_TAG "A2dpAudioInterface" #include <utils/Log.h> #include <utils/String8.h> Loading @@ -40,7 +40,7 @@ namespace android { //} A2dpAudioInterface::A2dpAudioInterface(AudioHardwareInterface* hw) : mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true) mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true), mSuspended(false) { } Loading Loading @@ -78,6 +78,7 @@ AudioStreamOut* A2dpAudioInterface::openOutputStream( if ((err = out->set(devices, format, channels, sampleRate)) == NO_ERROR) { mOutput = out; mOutput->setBluetoothEnabled(mBluetoothEnabled); mOutput->setSuspended(mSuspended); } else { delete out; } Loading Loading @@ -142,6 +143,14 @@ status_t A2dpAudioInterface::setParameters(const String8& keyValuePairs) } param.remove(key); } key = String8("A2dpSuspended"); if (param.get(key, value) == NO_ERROR) { mSuspended = (value == "true"); if (mOutput) { mOutput->setSuspended(mSuspended); } param.remove(key); } if (param.size()) { status_t hwStatus = mHardwareInterface->setParameters(param.toString()); Loading @@ -166,6 +175,12 @@ String8 A2dpAudioInterface::getParameters(const String8& keys) a2dpParam.add(key, value); param.remove(key); } key = "A2dpSuspended"; if (param.get(key, value) == NO_ERROR) { value = mSuspended ? "true" : "false"; a2dpParam.add(key, value); param.remove(key); } String8 keyValuePairs = a2dpParam.toString(); Loading Loading @@ -204,7 +219,7 @@ A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() : mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL), // assume BT enabled to start, this is safe because its only the // enabled->disabled transition we are worried about mBluetoothEnabled(true), mDevice(0), mClosing(false) mBluetoothEnabled(true), mDevice(0), mClosing(false), mSuspended(false) { // use any address by default strcpy(mA2dpAddress, "00:00:00:00:00:00"); Loading Loading @@ -258,8 +273,10 @@ ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t size_t remaining = bytes; status_t status = -1; if (!mBluetoothEnabled || mClosing) { LOGW("A2dpAudioStreamOut::write(), but bluetooth disabled"); if (!mBluetoothEnabled || mClosing || mSuspended) { LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \ mBluetoothEnabled %d, mClosing %d, mSuspended %d", mBluetoothEnabled, mClosing, mSuspended); goto Error; } Loading Loading @@ -408,6 +425,14 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::setBluetoothEnabled(bool enable return NO_ERROR; } status_t A2dpAudioInterface::A2dpAudioStreamOut::setSuspended(bool onOff) { LOGV("setSuspended %d", onOff); mSuspended = onOff; standby(); return NO_ERROR; } status_t A2dpAudioInterface::A2dpAudioStreamOut::close() { Mutex::Autolock lock(mLock); Loading
libs/audioflinger/A2dpAudioInterface.h +3 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ private: status_t close_l(); status_t setAddress(const char* address); status_t setBluetoothEnabled(bool enabled); status_t setSuspended(bool onOff); private: int mFd; Loading @@ -113,6 +114,7 @@ private: bool mBluetoothEnabled; uint32_t mDevice; bool mClosing; bool mSuspended; }; friend class A2dpAudioStreamOut; Loading @@ -121,6 +123,7 @@ private: AudioHardwareInterface *mHardwareInterface; char mA2dpAddress[20]; bool mBluetoothEnabled; bool mSuspended; }; Loading