Merge "Fix issue 3225810."

This commit is contained in:
Eric Laurent
2010-11-24 13:08:03 -08:00
committed by Android (Google) Code Review
2 changed files with 58 additions and 36 deletions

View File

@@ -23,10 +23,13 @@
#include "A2dpAudioInterface.h"
#include "audio/liba2dp.h"
#include <hardware_legacy/power.h>
namespace android {
static const char *sA2dpWakeLock = "A2dpOutputStream";
#define MAX_WRITE_RETRIES 5
// ----------------------------------------------------------------------------
//AudioHardwareInterface* A2dpAudioInterface::createA2dpInterface()
@@ -263,44 +266,55 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
{
LOGV("A2dpAudioStreamOut destructor");
standby();
close();
LOGV("A2dpAudioStreamOut destructor returning from close()");
}
ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
{
Mutex::Autolock lock(mLock);
size_t remaining = bytes;
status_t status = -1;
{
Mutex::Autolock lock(mLock);
if (!mBluetoothEnabled || mClosing || mSuspended) {
LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
mBluetoothEnabled %d, mClosing %d, mSuspended %d",
mBluetoothEnabled, mClosing, mSuspended);
goto Error;
}
size_t remaining = bytes;
status = init();
if (status < 0)
goto Error;
while (remaining > 0) {
status = a2dp_write(mData, buffer, remaining);
if (status <= 0) {
LOGE("a2dp_write failed err: %d\n", status);
if (!mBluetoothEnabled || mClosing || mSuspended) {
LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
mBluetoothEnabled %d, mClosing %d, mSuspended %d",
mBluetoothEnabled, mClosing, mSuspended);
goto Error;
}
remaining -= status;
buffer = ((char *)buffer) + status;
if (mStandby) {
acquire_wake_lock (PARTIAL_WAKE_LOCK, sA2dpWakeLock);
mStandby = false;
}
status = init();
if (status < 0)
goto Error;
int retries = MAX_WRITE_RETRIES;
while (remaining > 0 && retries) {
status = a2dp_write(mData, buffer, remaining);
if (status < 0) {
LOGE("a2dp_write failed err: %d\n", status);
goto Error;
}
if (status == 0) {
retries--;
}
remaining -= status;
buffer = (char *)buffer + status;
}
return bytes;
}
mStandby = false;
return bytes;
Error:
standby();
// Simulate audio output timing in case of error
usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);
@@ -324,19 +338,22 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::init()
status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
{
int result = 0;
if (mClosing) {
LOGV("Ignore standby, closing");
return result;
}
Mutex::Autolock lock(mLock);
return standby_l();
}
status_t A2dpAudioInterface::A2dpAudioStreamOut::standby_l()
{
int result = NO_ERROR;
if (!mStandby) {
result = a2dp_stop(mData);
if (result == 0)
mStandby = true;
LOGV_IF(mClosing || !mBluetoothEnabled, "Standby skip stop: closing %d enabled %d",
mClosing, mBluetoothEnabled);
if (!mClosing && mBluetoothEnabled) {
result = a2dp_stop(mData);
}
release_wake_lock(sA2dpWakeLock);
mStandby = true;
}
return result;
@@ -362,6 +379,9 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& ke
key = String8("closing");
if (param.get(key, value) == NO_ERROR) {
mClosing = (value == "true");
if (mClosing) {
standby();
}
param.remove(key);
}
key = AudioParameter::keyRouting;
@@ -444,6 +464,7 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
status_t A2dpAudioInterface::A2dpAudioStreamOut::close_l()
{
standby_l();
if (mData) {
LOGV("A2dpAudioStreamOut::close_l() calling a2dp_cleanup(mData)");
a2dp_cleanup(mData);

View File

@@ -103,6 +103,7 @@ private:
status_t setAddress(const char* address);
status_t setBluetoothEnabled(bool enabled);
status_t setSuspended(bool onOff);
status_t standby_l();
private:
int mFd;