summaryrefslogtreecommitdiffstats
path: root/media/libmedia/AudioSystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libmedia/AudioSystem.cpp')
-rw-r--r--media/libmedia/AudioSystem.cpp249
1 files changed, 187 insertions, 62 deletions
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 85ed2b1..4c2e77b 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -76,6 +76,25 @@ const sp<IAudioFlinger> AudioSystem::get_audio_flinger()
return af;
}
+const sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient()
+{
+ // calling get_audio_flinger() will initialize gAudioFlingerClient if needed
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == 0) return 0;
+ Mutex::Autolock _l(gLock);
+ return gAudioFlingerClient;
+}
+
+sp<AudioIoDescriptor> AudioSystem::getIoDescriptor(audio_io_handle_t ioHandle)
+{
+ sp<AudioIoDescriptor> desc;
+ const sp<AudioFlingerClient> afc = getAudioFlingerClient();
+ if (afc != 0) {
+ desc = afc->getIoDescriptor(ioHandle);
+ }
+ return desc;
+}
+
/* static */ status_t AudioSystem::checkAudioFlinger()
{
if (defaultServiceManager()->checkService(String16("media.audio_flinger")) != 0) {
@@ -249,9 +268,7 @@ status_t AudioSystem::getSamplingRate(audio_io_handle_t output,
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
-
- LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0);
- sp<AudioIoDescriptor> outputDesc = gAudioFlingerClient->getIoDescriptor(output);
+ sp<AudioIoDescriptor> outputDesc = getIoDescriptor(output);
if (outputDesc == 0) {
ALOGV("getOutputSamplingRate() no output descriptor for output %d in gOutputs", output);
*samplingRate = af->sampleRate(output);
@@ -290,9 +307,7 @@ status_t AudioSystem::getFrameCount(audio_io_handle_t output,
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
-
- LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0);
- sp<AudioIoDescriptor> outputDesc = gAudioFlingerClient->getIoDescriptor(output);
+ sp<AudioIoDescriptor> outputDesc = getIoDescriptor(output);
if (outputDesc == 0) {
*frameCount = af->frameCount(output);
} else {
@@ -329,9 +344,7 @@ status_t AudioSystem::getLatency(audio_io_handle_t output,
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
-
- LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0);
- sp<AudioIoDescriptor> outputDesc = gAudioFlingerClient->getIoDescriptor(output);
+ sp<AudioIoDescriptor> outputDesc = getIoDescriptor(output);
if (outputDesc == 0) {
*latency = af->latency(output);
} else {
@@ -346,10 +359,11 @@ status_t AudioSystem::getLatency(audio_io_handle_t output,
status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, audio_format_t format,
audio_channel_mask_t channelMask, size_t* buffSize)
{
- const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return PERMISSION_DENIED;
- LOG_ALWAYS_FATAL_IF(gAudioFlingerClient == 0);
- return gAudioFlingerClient->getInputBufferSize(sampleRate, format, channelMask, buffSize);
+ const sp<AudioFlingerClient> afc = getAudioFlingerClient();
+ if (afc == 0) {
+ return NO_INIT;
+ }
+ return afc->getInputBufferSize(sampleRate, format, channelMask, buffSize);
}
status_t AudioSystem::setVoiceVolume(float value)
@@ -446,47 +460,77 @@ void AudioSystem::AudioFlingerClient::ioConfigChanged(audio_io_config_event even
if (ioDesc == 0 || ioDesc->mIoHandle == AUDIO_IO_HANDLE_NONE) return;
- Mutex::Autolock _l(mLock);
+ audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
+ Vector < sp<AudioDeviceCallback> > callbacks;
- switch (event) {
- case AUDIO_OUTPUT_OPENED:
- case AUDIO_INPUT_OPENED: {
- if (getIoDescriptor(ioDesc->mIoHandle) != 0) {
- ALOGV("ioConfigChanged() opening already existing output! %d", ioDesc->mIoHandle);
- break;
- }
- mIoDescriptors.add(ioDesc->mIoHandle, ioDesc);
- ALOGV("ioConfigChanged() new %s opened %d samplingRate %u, format %#x channel mask %#x "
- "frameCount %zu", event == AUDIO_OUTPUT_OPENED ? "output" : "input",
- ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat, ioDesc->mChannelMask,
- ioDesc->mFrameCount);
- } break;
- case AUDIO_OUTPUT_CLOSED:
- case AUDIO_INPUT_CLOSED: {
- if (getIoDescriptor(ioDesc->mIoHandle) == 0) {
- ALOGW("ioConfigChanged() closing unknown %s %d",
+ {
+ Mutex::Autolock _l(mLock);
+
+ switch (event) {
+ case AUDIO_OUTPUT_OPENED:
+ case AUDIO_INPUT_OPENED: {
+ if (getIoDescriptor(ioDesc->mIoHandle) != 0) {
+ ALOGV("ioConfigChanged() opening already existing output! %d", ioDesc->mIoHandle);
+ break;
+ }
+ mIoDescriptors.add(ioDesc->mIoHandle, ioDesc);
+
+ if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
+ deviceId = ioDesc->getDeviceId();
+ ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(ioDesc->mIoHandle);
+ if (ioIndex >= 0) {
+ callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
+ }
+ }
+ ALOGV("ioConfigChanged() new %s opened %d samplingRate %u, format %#x channel mask %#x "
+ "frameCount %zu deviceId %d", event == AUDIO_OUTPUT_OPENED ? "output" : "input",
+ ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat, ioDesc->mChannelMask,
+ ioDesc->mFrameCount, ioDesc->getDeviceId());
+ } break;
+ case AUDIO_OUTPUT_CLOSED:
+ case AUDIO_INPUT_CLOSED: {
+ if (getIoDescriptor(ioDesc->mIoHandle) == 0) {
+ ALOGW("ioConfigChanged() closing unknown %s %d",
+ event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->mIoHandle);
+ break;
+ }
+ ALOGV("ioConfigChanged() %s %d closed",
event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->mIoHandle);
- break;
- }
- ALOGV("ioConfigChanged() %s %d closed", event == AUDIO_OUTPUT_CLOSED ? "output" : "input",
- ioDesc->mIoHandle);
- mIoDescriptors.removeItem(ioDesc->mIoHandle);
- } break;
+ mIoDescriptors.removeItem(ioDesc->mIoHandle);
+ mAudioDeviceCallbacks.removeItem(ioDesc->mIoHandle);
+ } break;
- case AUDIO_OUTPUT_CONFIG_CHANGED:
- case AUDIO_INPUT_CONFIG_CHANGED: {
- if (getIoDescriptor(ioDesc->mIoHandle) == 0) {
- ALOGW("ioConfigChanged() modifying unknown output! %d", ioDesc->mIoHandle);
- break;
+ case AUDIO_OUTPUT_CONFIG_CHANGED:
+ case AUDIO_INPUT_CONFIG_CHANGED: {
+ sp<AudioIoDescriptor> oldDesc = getIoDescriptor(ioDesc->mIoHandle);
+ if (oldDesc == 0) {
+ ALOGW("ioConfigChanged() modifying unknown output! %d", ioDesc->mIoHandle);
+ break;
+ }
+
+ deviceId = oldDesc->getDeviceId();
+ mIoDescriptors.replaceValueFor(ioDesc->mIoHandle, ioDesc);
+
+ if (deviceId != ioDesc->getDeviceId()) {
+ deviceId = ioDesc->getDeviceId();
+ ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(ioDesc->mIoHandle);
+ if (ioIndex >= 0) {
+ callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
+ }
+ }
+ ALOGV("ioConfigChanged() new config for %s %d samplingRate %u, format %#x "
+ "channel mask %#x frameCount %zu deviceId %d",
+ event == AUDIO_OUTPUT_CONFIG_CHANGED ? "output" : "input",
+ ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat,
+ ioDesc->mChannelMask, ioDesc->mFrameCount, ioDesc->getDeviceId());
+
+ } break;
}
- mIoDescriptors.replaceValueFor(ioDesc->mIoHandle, ioDesc);
- ALOGV("ioConfigChanged() new config for %s %d samplingRate %u, format %#x "
- "channel mask %#x frameCount %zu",
- event == AUDIO_OUTPUT_CONFIG_CHANGED ? "output" : "input",
- ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat,
- ioDesc->mChannelMask, ioDesc->mFrameCount);
- } break;
+ }
+ // callbacks.size() != 0 => ioDesc->mIoHandle and deviceId are valid
+ for (size_t i = 0; i < callbacks.size(); i++) {
+ callbacks[i]->onAudioDeviceUpdate(ioDesc->mIoHandle, deviceId);
}
}
@@ -532,7 +576,56 @@ sp<AudioIoDescriptor> AudioSystem::AudioFlingerClient::getIoDescriptor(audio_io_
return desc;
}
-/*static*/ void AudioSystem::setErrorCallback(audio_error_callback cb)
+status_t AudioSystem::AudioFlingerClient::addAudioDeviceCallback(
+ const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+{
+ Mutex::Autolock _l(mLock);
+ Vector < sp<AudioDeviceCallback> > callbacks;
+ ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(audioIo);
+ if (ioIndex >= 0) {
+ callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
+ }
+
+ for (size_t cbIndex = 0; cbIndex < callbacks.size(); cbIndex++) {
+ if (callbacks[cbIndex] == callback) {
+ return INVALID_OPERATION;
+ }
+ }
+ callbacks.add(callback);
+
+ mAudioDeviceCallbacks.replaceValueFor(audioIo, callbacks);
+ return NO_ERROR;
+}
+
+status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
+ const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+{
+ Mutex::Autolock _l(mLock);
+ ssize_t ioIndex = mAudioDeviceCallbacks.indexOfKey(audioIo);
+ if (ioIndex < 0) {
+ return INVALID_OPERATION;
+ }
+ Vector < sp<AudioDeviceCallback> > callbacks = mAudioDeviceCallbacks.valueAt(ioIndex);
+
+ size_t cbIndex;
+ for (cbIndex = 0; cbIndex < callbacks.size(); cbIndex++) {
+ if (callbacks[cbIndex] == callback) {
+ break;
+ }
+ }
+ if (cbIndex == callbacks.size()) {
+ return INVALID_OPERATION;
+ }
+ callbacks.removeAt(cbIndex);
+ if (callbacks.size() != 0) {
+ mAudioDeviceCallbacks.replaceValueFor(audioIo, callbacks);
+ } else {
+ mAudioDeviceCallbacks.removeItem(audioIo);
+ }
+ return NO_ERROR;
+}
+
+/* static */ void AudioSystem::setErrorCallback(audio_error_callback cb)
{
Mutex::Autolock _l(gLock);
gAudioErrorCallback = cb;
@@ -864,11 +957,11 @@ void AudioSystem::clearAudioConfigCache()
{
// called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances
ALOGV("clearAudioConfigCache()");
- if (gAudioFlingerClient != 0) {
- gAudioFlingerClient->clearIoCache();
- }
{
Mutex::Autolock _l(gLock);
+ if (gAudioFlingerClient != 0) {
+ gAudioFlingerClient->clearIoCache();
+ }
gAudioFlinger.clear();
}
{
@@ -934,7 +1027,7 @@ status_t AudioSystem::setAudioPortConfig(const struct audio_port_config *config)
return aps->setAudioPortConfig(config);
}
-status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callBack)
+status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callback)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -943,11 +1036,11 @@ status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callBack
if (gAudioPolicyServiceClient == 0) {
return NO_INIT;
}
- return gAudioPolicyServiceClient->addAudioPortCallback(callBack);
+ return gAudioPolicyServiceClient->addAudioPortCallback(callback);
}
/*static*/
-status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callBack)
+status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callback)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -956,7 +1049,38 @@ status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callB
if (gAudioPolicyServiceClient == 0) {
return NO_INIT;
}
- return gAudioPolicyServiceClient->removeAudioPortCallback(callBack);
+ return gAudioPolicyServiceClient->removeAudioPortCallback(callback);
+}
+
+status_t AudioSystem::addAudioDeviceCallback(
+ const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+{
+ const sp<AudioFlingerClient> afc = getAudioFlingerClient();
+ if (afc == 0) {
+ return NO_INIT;
+ }
+ return afc->addAudioDeviceCallback(callback, audioIo);
+}
+
+status_t AudioSystem::removeAudioDeviceCallback(
+ const sp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+{
+ const sp<AudioFlingerClient> afc = getAudioFlingerClient();
+ if (afc == 0) {
+ return NO_INIT;
+ }
+ return afc->removeAudioDeviceCallback(callback, audioIo);
+}
+
+audio_port_handle_t AudioSystem::getDeviceIdForIo(audio_io_handle_t audioIo)
+{
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == 0) return PERMISSION_DENIED;
+ const sp<AudioIoDescriptor> desc = getIoDescriptor(audioIo);
+ if (desc == 0) {
+ return AUDIO_PORT_HANDLE_NONE;
+ }
+ return desc->getDeviceId();
}
status_t AudioSystem::acquireSoundTriggerSession(audio_session_t *session,
@@ -1008,25 +1132,25 @@ status_t AudioSystem::stopAudioSource(audio_io_handle_t handle)
// ---------------------------------------------------------------------------
status_t AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
- const sp<AudioPortCallback>& callBack)
+ const sp<AudioPortCallback>& callback)
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
- if (mAudioPortCallbacks[i] == callBack) {
+ if (mAudioPortCallbacks[i] == callback) {
return INVALID_OPERATION;
}
}
- mAudioPortCallbacks.add(callBack);
+ mAudioPortCallbacks.add(callback);
return NO_ERROR;
}
status_t AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback(
- const sp<AudioPortCallback>& callBack)
+ const sp<AudioPortCallback>& callback)
{
Mutex::Autolock _l(mLock);
size_t i;
for (i = 0; i < mAudioPortCallbacks.size(); i++) {
- if (mAudioPortCallbacks[i] == callBack) {
+ if (mAudioPortCallbacks[i] == callback) {
break;
}
}
@@ -1037,6 +1161,7 @@ status_t AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback(
return NO_ERROR;
}
+
void AudioSystem::AudioPolicyServiceClient::onAudioPortListUpdate()
{
Mutex::Autolock _l(mLock);