summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy/service
diff options
context:
space:
mode:
authorSteve Kondik <steve@cyngn.com>2016-04-06 18:35:02 -0700
committerSteve Kondik <steve@cyngn.com>2016-04-07 15:19:57 -0700
commita4123803d0a0e9e0c69faa4207d357cc74a65d58 (patch)
tree336ade2306784822373a6a18023136090dd6d343 /services/audiopolicy/service
parente13b58b988ab642d4ae5ca6d0a89013510714956 (diff)
downloadframeworks_av-a4123803d0a0e9e0c69faa4207d357cc74a65d58.zip
frameworks_av-a4123803d0a0e9e0c69faa4207d357cc74a65d58.tar.gz
frameworks_av-a4123803d0a0e9e0c69faa4207d357cc74a65d58.tar.bz2
audiopolicy: Be a little smarter with auto-attach
* The edge cases, ZOMG! * Instead of relying on effects to be automatically attached, let's just always notify userspace and send a bit more information. This lets the application decide if effects should be attached rather than relying on a hard-coded configuration file. * Perform the setup in getOutputForAttr, but do it on the command thread so we don't block the client. OPO-593 Change-Id: I3900b349f2e895d51fa3a3dcc2de0c4bdf6dbc08
Diffstat (limited to 'services/audiopolicy/service')
-rw-r--r--services/audiopolicy/service/AudioPolicyClientImpl.cpp7
-rw-r--r--services/audiopolicy/service/AudioPolicyEffects.cpp32
-rw-r--r--services/audiopolicy/service/AudioPolicyEffects.h5
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp68
-rw-r--r--services/audiopolicy/service/AudioPolicyService.cpp72
-rw-r--r--services/audiopolicy/service/AudioPolicyService.h55
6 files changed, 191 insertions, 48 deletions
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index d71daa4..f1a2ae9 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -220,9 +220,12 @@ void AudioPolicyService::AudioPolicyClient::onDynamicPolicyMixStateUpdate(
}
void AudioPolicyService::AudioPolicyClient::onOutputSessionEffectsUpdate(
- audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
+ audio_stream_type_t stream, audio_session_t sessionId,
+ audio_output_flags_t flags, audio_channel_mask_t channelMask,
+ uid_t uid, bool added)
{
- mAudioPolicyService->onOutputSessionEffectsUpdate(stream, sessionId, added);
+ mAudioPolicyService->onOutputSessionEffectsUpdate(stream, sessionId,
+ flags, channelMask, uid, added);
}
audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId()
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index 725bc64..bd1cc33 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -246,6 +246,7 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
if (idx < 0) {
procDesc = new EffectVector(audioSession);
mOutputSessions.add(audioSession, procDesc);
+
} else {
// EffectVector is existing and we just need to increase ref count
procDesc = mOutputSessions.valueAt(idx);
@@ -273,11 +274,35 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
}
procDesc->setProcessorEnabled(true);
- return 1;
}
return status;
}
+status_t AudioPolicyEffects::doAddOutputSessionEffects(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ int session,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask, uid_t uid)
+{
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ return BAD_VALUE;
+ }
+ ALOGV("doAddOutputSessionEffects()");
+
+ // create audio processors according to stream
+ status_t status = addOutputSessionEffects(output, stream, session);
+ if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) {
+ ALOGW("Failed to add effects on session %d", session);
+ }
+
+ // notify listeners
+ mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)session,
+ flags, channelMask, uid, true);
+
+ // Never return an error if effects setup fails.
+ return NO_ERROR;
+}
+
status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
int audioSession)
@@ -335,10 +360,13 @@ status_t AudioPolicyEffects::doReleaseOutputSessionEffects(audio_io_handle_t out
procDesc->mEffects.clear();
delete procDesc;
mOutputSessions.removeItemsAt(index);
- mAudioPolicyService->onOutputSessionEffectsUpdate(stream, audioSession, false);
ALOGV("doReleaseOutputSessionEffects(): output processing released from session: %d",
audioSession);
}
+
+ mAudioPolicyService->onOutputSessionEffectsUpdate(stream, (audio_session_t)audioSession,
+ AUDIO_OUTPUT_FLAG_NONE, 0, -1, false);
+
return status;
}
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 7988515..6364e40 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -91,6 +91,11 @@ public:
audio_stream_type_t stream,
int audioSession);
+ status_t doAddOutputSessionEffects(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ int audioSession,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ audio_channel_mask_t channelMask = 0, uid_t uid = 0);
private:
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 766012e..51af20b 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include <utils/Log.h>
+#include <media/AudioPolicyHelper.h>
#include "AudioPolicyService.h"
#include "ServiceUtilities.h"
@@ -162,18 +163,47 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
return NO_INIT;
}
ALOGV("getOutput()");
- Mutex::Autolock _l(mLock);
+ status_t status;
+ sp<AudioPolicyEffects> audioPolicyEffects;
+ {
+ Mutex::Autolock _l(mLock);
- // if the caller is us, trust the specified uid
- if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
- uid_t newclientUid = IPCThreadState::self()->getCallingUid();
- if (uid != (uid_t)-1 && uid != newclientUid) {
- ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
+ // if the caller is us, trust the specified uid
+ if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
+ uid_t newclientUid = IPCThreadState::self()->getCallingUid();
+ if (uid != (uid_t)-1 && uid != newclientUid) {
+ ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
+ }
+ uid = newclientUid;
}
- uid = newclientUid;
+ status = mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,
+ format, channelMask, flags, selectedDeviceId, offloadInfo);
+ audioPolicyEffects = mAudioPolicyEffects;
+ }
+
+ if (audioPolicyEffects != 0) {
+ addOutputSessionEffects(*output, *stream, session, flags, channelMask, uid);
+ }
+
+ return status;
+}
+
+status_t AudioPolicyService::addOutputSessionEffects(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid)
+{
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ return BAD_VALUE;
}
- return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,
- format, channelMask, flags, selectedDeviceId, offloadInfo);
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ ALOGV("addOutputSessionEffects()");
+ return mOutputCommandThread->addOutputSessionEffectsCommand(
+ output, stream, session, flags, channelMask, uid);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -201,27 +231,9 @@ status_t AudioPolicyService::doStartOutput(audio_io_handle_t output,
return NO_INIT;
}
ALOGV("doStartOutput()");
- sp<AudioPolicyEffects>audioPolicyEffects;
- {
- Mutex::Autolock _l(mLock);
- audioPolicyEffects = mAudioPolicyEffects;
- }
-
- status_t status = NO_ERROR;
- if (audioPolicyEffects != 0) {
- // create audio processors according to stream
- status = audioPolicyEffects->addOutputSessionEffects(output, stream, session);
- if (status <= 0 && (status != NO_ERROR && status != ALREADY_EXISTS)) {
- ALOGW("Failed to add effects on session %d", session);
- }
- }
Mutex::Autolock _l(mLock);
- status_t status2 = mAudioPolicyManager->startOutput(output, stream, session);
- if (audioPolicyEffects != 0 && status > 0 && status2 == NO_ERROR) {
- onOutputSessionEffectsUpdate(stream, session, true);
- }
- return status2;
+ return mAudioPolicyManager->startOutput(output, stream, session);
}
status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 58cfe37..0e871c2 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -272,21 +272,27 @@ status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_co
}
void AudioPolicyService::onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId,
- bool added)
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid, bool added)
{
ALOGV("AudioPolicyService::onOutputSessionEffectsUpdate(%d, %d, %d)",
stream, sessionId, added);
- mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId, added);
+ mOutputCommandThread->effectSessionUpdateCommand(stream, sessionId,
+ flags, channelMask, uid, added);
}
void AudioPolicyService::doOnOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId,
- bool added)
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid, bool added)
{
Mutex::Autolock _l(mNotificationClientsLock);
for (size_t i = 0; i < mNotificationClients.size(); i++) {
- mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId, added);
+ mNotificationClients.valueAt(i)->onOutputSessionEffectsUpdate(stream, sessionId,
+ flags, channelMask, uid, added);
}
}
@@ -327,10 +333,13 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
}
void AudioPolicyService::NotificationClient::onOutputSessionEffectsUpdate(
- audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
+ audio_stream_type_t stream, audio_session_t sessionId,
+ audio_output_flags_t flags, audio_channel_mask_t channelMask,
+ uid_t uid, bool added)
{
if (mAudioPolicyServiceClient != 0 && mEffectSessionCallbacksEnabled) {
- mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId, added);
+ mAudioPolicyServiceClient->onOutputSessionEffectsUpdate(stream, sessionId,
+ flags, channelMask, uid, added);
}
}
@@ -645,7 +654,8 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
break;
}
mLock.unlock();
- svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId, data->mAdded);
+ svc->doOnOutputSessionEffectsUpdate(data->mStream, data->mSessionId,
+ data->mFlags, data->mChannelMask, data->mUid, data->mAdded);
mLock.lock();
} break;
case RELEASE_OUTPUT_SESSION_EFFECTS: {
@@ -662,6 +672,20 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
data->mOutput, data->mStream, data->mSessionId);
mLock.lock();
} break;
+ case ADD_OUTPUT_SESSION_EFFECTS: {
+ AddOutputSessionEffectsData *data = (AddOutputSessionEffectsData *)command->mParam.get();
+ ALOGV("AudioCommandThread() processing add output session effects %d",
+ data->mOutput);
+ svc = mService.promote();
+ if (svc == 0) {
+ break;
+ }
+ mLock.unlock();
+ svc->mAudioPolicyEffects->doAddOutputSessionEffects(
+ data->mOutput, data->mStream, data->mSessionId,
+ data->mFlags, data->mChannelMask, data->mUid);
+ mLock.lock();
+ }break;
default:
@@ -828,6 +852,29 @@ status_t AudioPolicyService::AudioCommandThread::startOutputCommand(audio_io_han
return sendCommand(command);
}
+status_t AudioPolicyService::AudioCommandThread::addOutputSessionEffectsCommand(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid)
+{
+ sp<AudioCommand> command = new AudioCommand();
+ command->mCommand = ADD_OUTPUT_SESSION_EFFECTS;
+ sp<AddOutputSessionEffectsData> data = new AddOutputSessionEffectsData();
+ data->mOutput = output;
+ data->mStream = stream;
+ data->mSessionId = session;
+ data->mFlags = flags;
+ data->mChannelMask = channelMask;
+ data->mUid = uid;
+ command->mParam = data;
+ command->mWaitStatus = false;
+ ALOGV("AudioCommandThread() adding start output %d", output);
+ return sendCommand(command);
+}
+
+
void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
@@ -937,13 +984,18 @@ void AudioPolicyService::AudioCommandThread::dynamicPolicyMixStateUpdateCommand(
}
void AudioPolicyService::AudioCommandThread::effectSessionUpdateCommand(
- audio_stream_type_t stream, audio_unique_id_t sessionId, bool added)
+ audio_stream_type_t stream, audio_session_t sessionId,
+ audio_output_flags_t flags, audio_channel_mask_t channelMask,
+ uid_t uid, bool added)
{
sp<AudioCommand> command = new AudioCommand();
command->mCommand = EFFECT_SESSION_UPDATE;
EffectSessionUpdateData *data = new EffectSessionUpdateData();
data->mStream = stream;
data->mSessionId = sessionId;
+ data->mFlags = flags;
+ data->mChannelMask = channelMask;
+ data->mUid = uid;
data->mAdded = added;
command->mParam = data;
ALOGV("AudioCommandThread() sending effect session update (id=%d) for stream %d (added=%d)",
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 9b17a26..01e0e5e 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -204,6 +204,13 @@ public:
virtual status_t setEffectSessionCallbacksEnabled(bool enabled);
+ virtual status_t addOutputSessionEffects(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid);
+
status_t doStartOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
@@ -232,9 +239,15 @@ public:
void doOnDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid, bool added);
void doOnOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid, bool added);
void releaseOutputSessionEffectsDelayed(audio_io_handle_t output,
audio_stream_type_t stream,
audio_unique_id_t sessionId,
@@ -274,6 +287,7 @@ private:
DYN_POLICY_MIX_STATE_UPDATE,
EFFECT_SESSION_UPDATE,
RELEASE_OUTPUT_SESSION_EFFECTS,
+ ADD_OUTPUT_SESSION_EFFECTS
};
AudioCommandThread (String8 name, const wp<AudioPolicyService>& service);
@@ -317,11 +331,21 @@ private:
void dynamicPolicyMixStateUpdateCommand(String8 regId, int32_t state);
void insertCommand_l(AudioCommand *command, int delayMs = 0);
void effectSessionUpdateCommand(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid, bool added);
void releaseOutputSessionEffectsCommand(audio_io_handle_t output,
audio_stream_type_t stream,
audio_unique_id_t sessionId,
int delayMs = 0);
+ status_t addOutputSessionEffectsCommand(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid);
+
private:
class AudioCommandData;
@@ -421,7 +445,10 @@ private:
class EffectSessionUpdateData : public AudioCommandData {
public:
audio_stream_type_t mStream;
- audio_unique_id_t mSessionId;
+ audio_session_t mSessionId;
+ audio_output_flags_t mFlags;
+ audio_channel_mask_t mChannelMask;
+ uid_t mUid;
bool mAdded;
};
@@ -432,6 +459,16 @@ private:
audio_unique_id_t mSessionId;
};
+ class AddOutputSessionEffectsData : public AudioCommandData {
+ public:
+ audio_io_handle_t mOutput;
+ audio_stream_type_t mStream;
+ audio_session_t mSessionId;
+ audio_output_flags_t mFlags;
+ audio_channel_mask_t mChannelMask;
+ uid_t mUid;
+ };
+
Mutex mLock;
Condition mWaitWorkCV;
Vector < sp<AudioCommand> > mAudioCommands; // list of pending commands
@@ -542,7 +579,10 @@ private:
virtual audio_unique_id_t newAudioUniqueId();
virtual void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid, bool added);
private:
AudioPolicyService *mAudioPolicyService;
@@ -562,7 +602,10 @@ private:
void setAudioPortCallbacksEnabled(bool enabled);
void setEffectSessionCallbacksEnabled(bool enabled);
void onOutputSessionEffectsUpdate(audio_stream_type_t stream,
- audio_unique_id_t sessionId, bool added);
+ audio_session_t sessionId,
+ audio_output_flags_t flags,
+ audio_channel_mask_t channelMask,
+ uid_t uid, bool added);
// IBinder::DeathRecipient
virtual void binderDied(const wp<IBinder>& who);