summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/server/BluetoothA2dpService.java56
-rw-r--r--libs/audioflinger/A2dpAudioInterface.cpp35
-rw-r--r--libs/audioflinger/A2dpAudioInterface.h3
3 files changed, 85 insertions, 9 deletions
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index b73e53f..9a2d6d9 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -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);
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index 57a29f2..351815b 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -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);
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 35a6e11..530e432 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -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;
};