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:
Android (Google) Code Review
2009-10-08 17:36:18 -04:00
3 changed files with 85 additions and 9 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
};