Merge change I80a6a229 into eclair
* changes: Fix issue 2174002: After rejecting Call when device ringtone is mute and playing music, audio is not transfered to BT device.
This commit is contained in:
@ -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
|
||||
@ -149,6 +151,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
|
||||
if (mBluetoothService.isEnabled())
|
||||
onBluetoothEnable();
|
||||
mSuspending = false;
|
||||
mResuming = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -241,6 +245,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
}
|
||||
}
|
||||
mAudioManager.setParameters(BLUETOOTH_ENABLED+"=true");
|
||||
mAudioManager.setParameters("A2dpSuspended=false");
|
||||
}
|
||||
|
||||
private synchronized void onBluetoothDisable() {
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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) {
|
||||
@ -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);
|
||||
|
@ -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>
|
||||
@ -40,7 +40,7 @@ namespace android {
|
||||
//}
|
||||
|
||||
A2dpAudioInterface::A2dpAudioInterface(AudioHardwareInterface* hw) :
|
||||
mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true)
|
||||
mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true), mSuspended(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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());
|
||||
@ -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();
|
||||
|
||||
@ -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");
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
@ -113,6 +114,7 @@ private:
|
||||
bool mBluetoothEnabled;
|
||||
uint32_t mDevice;
|
||||
bool mClosing;
|
||||
bool mSuspended;
|
||||
};
|
||||
|
||||
friend class A2dpAudioStreamOut;
|
||||
@ -121,6 +123,7 @@ private:
|
||||
AudioHardwareInterface *mHardwareInterface;
|
||||
char mA2dpAddress[20];
|
||||
bool mBluetoothEnabled;
|
||||
bool mSuspended;
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user