summaryrefslogtreecommitdiff
path: root/libs/audioflinger/A2dpAudioInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/audioflinger/A2dpAudioInterface.cpp')
-rw-r--r--libs/audioflinger/A2dpAudioInterface.cpp76
1 files changed, 48 insertions, 28 deletions
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index c8c8431096d7..2974e32ee179 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -48,7 +48,6 @@ AudioStreamOut* A2dpAudioInterface::openOutputStream(
int format, int channelCount, uint32_t sampleRate, status_t *status)
{
LOGD("A2dpAudioInterface::openOutputStream %d, %d, %d\n", format, channelCount, sampleRate);
- Mutex::Autolock lock(mLock);
status_t err = 0;
// only one output stream allowed
@@ -72,7 +71,8 @@ AudioStreamOut* A2dpAudioInterface::openOutputStream(
}
AudioStreamIn* A2dpAudioInterface::openInputStream(
- int format, int channelCount, uint32_t sampleRate, status_t *status)
+ int format, int channelCount, uint32_t sampleRate, status_t *status,
+ AudioSystem::audio_in_acoustics acoustics)
{
if (status)
*status = -1;
@@ -99,6 +99,10 @@ status_t A2dpAudioInterface::setParameter(const char *key, const char *value)
if (strcmp(key, "a2dp_sink_address") == 0) {
return mOutput->setAddress(value);
}
+ if (strcmp(key, "bluetooth_enabled") == 0 &&
+ strcmp(value, "false") == 0) {
+ return mOutput->close();
+ }
return 0;
}
@@ -126,11 +130,11 @@ status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
// ----------------------------------------------------------------------------
A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
- mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL),
- mInitialized(false)
+ mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL)
{
// use any address by default
- strncpy(mA2dpAddress, "00:00:00:00:00:00", sizeof(mA2dpAddress));
+ strcpy(mA2dpAddress, "00:00:00:00:00:00");
+ init();
}
status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
@@ -154,23 +158,17 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
{
- if (mData)
- a2dp_cleanup(mData);
+ close();
}
ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
{
- status_t status = NO_INIT;
- size_t remaining = bytes;
+ Mutex::Autolock lock(mLock);
- if (!mInitialized) {
- status = a2dp_init(mA2dpAddress, 44100, 2, &mData);
- if (status < 0) {
- LOGE("a2dp_init failed err: %d\n", status);
- goto Error;
- }
- mInitialized = true;
- }
+ size_t remaining = bytes;
+ status_t status = init();
+ if (status < 0)
+ goto Error;
while (remaining > 0) {
status = a2dp_write(mData, buffer, remaining);
@@ -186,17 +184,34 @@ ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t
return bytes;
-Error:
+Error:
// Simulate audio output timing in case of error
usleep(bytes * 1000000 / frameSize() / sampleRate());
return status;
}
+status_t A2dpAudioInterface::A2dpAudioStreamOut::init()
+{
+ if (!mData) {
+ status_t status = a2dp_init(44100, 2, &mData);
+ if (status < 0) {
+ LOGE("a2dp_init failed err: %d\n", status);
+ mData = NULL;
+ return status;
+ }
+ a2dp_set_sink(mData, mA2dpAddress);
+ }
+
+ return 0;
+}
+
status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
{
int result = 0;
+ Mutex::Autolock lock(mLock);
+
if (!mStandby) {
result = a2dp_stop(mData);
if (result == 0)
@@ -208,19 +223,24 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
{
- if (strlen(address) < sizeof(mA2dpAddress))
+ Mutex::Autolock lock(mLock);
+
+ if (strlen(address) != strlen("00:00:00:00:00:00"))
return -EINVAL;
- if (strcmp(address, mA2dpAddress)) {
- strcpy(mA2dpAddress, address);
-
- if (mInitialized) {
- a2dp_cleanup(mData);
- mData = NULL;
- mInitialized = false;
- }
+ strcpy(mA2dpAddress, address);
+ if (mData)
+ a2dp_set_sink(mData, mA2dpAddress);
+
+ return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
+{
+ if (mData) {
+ a2dp_cleanup(mData);
+ mData = NULL;
}
-
return NO_ERROR;
}