audio policy: refactor record activity tracking (AudioSession)
Refactor input activity ref counting and callbacks to align
with implementation for output.
This will help migration to per client activity tracking.
Test: audio smoke test, CTS for AudioRecord
Change-Id: I8806446f33d3090f1042e0956df81318646d5285
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index 9f3fc0c..555412e 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -34,12 +34,4 @@
virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
};
-class AudioIODescriptorUpdateListener
-{
-public:
- virtual ~AudioIODescriptorUpdateListener() {};
-
- virtual void onIODescriptorUpdate() const = 0;
-};
-
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 85f3b86..ca837c4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -66,6 +66,8 @@
AudioSessionCollection getAudioSessions(bool activeOnly) const;
size_t getAudioSessionCount(bool activeOnly) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
+ void changeRefCount(audio_session_t session, int delta);
+
// implementation of AudioIODescriptorInterface
audio_config_base_t getConfig() const override;
@@ -79,14 +81,17 @@
audio_input_flags_t flags,
audio_io_handle_t *input);
// Called when a stream is about to be started.
- // Note: called after AudioSession::changeActiveCount(1)
+ // Note: called after changeRefCount(session, 1)
status_t start();
// Called after a stream is stopped
- // Note: called after AudioSession::changeActiveCount(-1)
+ // Note: called after changeRefCount(session, -1)
void stop();
void close();
private:
+
+ void updateSessionRecordingConfiguration(int event, const sp<AudioSession>& audioSession);
+
audio_patch_handle_t mPatchHandle;
audio_port_handle_t mId;
// audio sessions attached to this input
@@ -99,6 +104,7 @@
// We also inherit sessions from the preempted input to avoid a 3 way preemption loop etc...
SortedVector<audio_session_t> mPreemptedSessions;
AudioPolicyClientInterface *mClientInterface;
+ uint32_t mGlobalRefCount; // non-session-specific ref count
};
class AudioInputCollection :
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index 53e6ec9..1636d3a 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -29,7 +29,7 @@
class AudioPolicyClientInterface;
-class AudioSession : public RefBase, public AudioIODescriptorUpdateListener
+class AudioSession : public RefBase
{
public:
AudioSession(audio_session_t session,
@@ -39,9 +39,7 @@
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
uid_t uid,
- bool isSoundTrigger,
- AudioMix* policyMix,
- AudioPolicyClientInterface *clientInterface);
+ bool isSoundTrigger);
status_t dump(int fd, int spaces, int index) const;
@@ -50,6 +48,8 @@
audio_format_t format() const { return mConfig.format; }
uint32_t sampleRate() const { return mConfig.sample_rate; }
audio_channel_mask_t channelMask() const { return mConfig.channel_mask; }
+ audio_config_base config() const { return mConfig; }
+ record_client_info_t recordClientInfo() const { return mRecordClientInfo; }
audio_input_flags_t flags() const { return mFlags; }
uid_t uid() const { return mRecordClientInfo.uid; }
void setUid(uid_t uid) { mRecordClientInfo.uid = uid; }
@@ -63,10 +63,6 @@
uint32_t changeOpenCount(int delta);
uint32_t changeActiveCount(int delta);
- void setInfoProvider(AudioIODescriptorInterface *provider);
- // implementation of AudioIODescriptorUpdateListener
- virtual void onIODescriptorUpdate() const;
-
private:
record_client_info_t mRecordClientInfo;
const struct audio_config_base mConfig;
@@ -75,19 +71,14 @@
bool mSilenced;
uint32_t mOpenCount;
uint32_t mActiveCount;
- AudioMix* mPolicyMix; // non NULL when used by a dynamic policy
- AudioPolicyClientInterface* mClientInterface;
- const AudioIODescriptorInterface* mInfoProvider;
};
class AudioSessionCollection :
- public DefaultKeyedVector<audio_session_t, sp<AudioSession> >,
- public AudioIODescriptorUpdateListener
+ public DefaultKeyedVector<audio_session_t, sp<AudioSession> >
{
public:
status_t addSession(audio_session_t session,
- const sp<AudioSession>& audioSession,
- AudioIODescriptorInterface *provider);
+ const sp<AudioSession>& audioSession);
status_t removeSession(audio_session_t session);
@@ -99,9 +90,6 @@
bool isSourceActive(audio_source_t source) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
- // implementation of AudioIODescriptorUpdateListener
- virtual void onIODescriptorUpdate() const;
-
status_t dump(int fd, int spaces) const;
};
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index f0144db..b9895a9 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -32,7 +32,7 @@
: mIoHandle(0),
mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0),
- mClientInterface(clientInterface)
+ mClientInterface(clientInterface), mGlobalRefCount(0)
{
if (profile != NULL) {
profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
@@ -164,7 +164,7 @@
status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
const sp<AudioSession>& audioSession) {
- return mSessions.addSession(session, audioSession, /*AudioIODescriptorInterface*/this);
+ return mSessions.addSession(session, audioSession);
}
status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
@@ -179,7 +179,11 @@
void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
{
mPatchHandle = handle;
- mSessions.onIODescriptorUpdate();
+ for (size_t i = 0; i < mSessions.size(); i++) {
+ if (mSessions[i]->activeCount() > 0) {
+ updateSessionRecordingConfiguration(RECORD_CONFIG_EVENT_START, mSessions[i]);
+ }
+ }
}
audio_config_base_t AudioInputDescriptor::getConfig() const
@@ -266,7 +270,7 @@
LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
__FUNCTION__, mProfile->curOpenCount);
// do not call stop() here as stop() is supposed to be called after
- // AudioSession::changeActiveCount(-1) and we don't know how many sessions
+ // changeRefCount(session, -1) and we don't know how many sessions
// are still active at this time
if (isActive()) {
mProfile->curActiveCount--;
@@ -276,6 +280,66 @@
}
}
+void AudioInputDescriptor::changeRefCount(audio_session_t session, int delta)
+{
+ sp<AudioSession> audioSession = mSessions.valueFor(session);
+ if (audioSession == 0) {
+ return;
+ }
+ // handle session-independent ref count
+ uint32_t oldGlobalRefCount = mGlobalRefCount;
+ if ((delta + (int)mGlobalRefCount) < 0) {
+ ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
+ delta = -((int)mGlobalRefCount);
+ }
+ mGlobalRefCount += delta;
+ if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
+ if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+ {
+ mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
+ MIX_STATE_MIXING);
+ }
+
+ } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
+ if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+ {
+ mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
+ MIX_STATE_IDLE);
+ }
+ }
+
+ uint32_t oldActiveCount = audioSession->activeCount();
+ if ((delta + (int)oldActiveCount) < 0) {
+ ALOGW("changeRefCount() invalid delta %d for sesion %d active count %d",
+ delta, session, oldActiveCount);
+ delta = -((int)oldActiveCount);
+ }
+
+ audioSession->changeActiveCount(delta);
+
+ int event = RECORD_CONFIG_EVENT_NONE;
+ if ((oldActiveCount == 0) && (audioSession->activeCount() > 0)) {
+ event = RECORD_CONFIG_EVENT_START;
+ } else if ((oldActiveCount > 0) && (audioSession->activeCount() == 0)) {
+ event = RECORD_CONFIG_EVENT_STOP;
+ }
+ if (event != RECORD_CONFIG_EVENT_NONE) {
+ updateSessionRecordingConfiguration(event, audioSession);
+ }
+
+}
+
+void AudioInputDescriptor::updateSessionRecordingConfiguration(
+ int event, const sp<AudioSession>& audioSession) {
+
+ const audio_config_base_t sessionConfig = audioSession->config();
+ const record_client_info_t recordClientInfo = audioSession->recordClientInfo();
+ const audio_config_base_t config = getConfig();
+ mClientInterface->onRecordingConfigurationUpdate(event,
+ &recordClientInfo, &sessionConfig,
+ &config, mPatchHandle);
+}
+
status_t AudioInputDescriptor::dump(int fd)
{
const size_t SIZE = 256;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index 91dee35..5ea4c92 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -35,14 +35,11 @@
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
uid_t uid,
- bool isSoundTrigger,
- AudioMix* policyMix,
- AudioPolicyClientInterface *clientInterface) :
+ bool isSoundTrigger) :
mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
mFlags(flags), mIsSoundTrigger(isSoundTrigger),
- mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface),
- mInfoProvider(NULL)
+ mOpenCount(1), mActiveCount(0)
{
}
@@ -60,7 +57,6 @@
uint32_t AudioSession::changeActiveCount(int delta)
{
- const uint32_t oldActiveCount = mActiveCount;
if ((delta + (int)mActiveCount) < 0) {
ALOGW("%s invalid delta %d, active count %d",
__FUNCTION__, delta, mActiveCount);
@@ -68,34 +64,6 @@
}
mActiveCount += delta;
ALOGV("%s active count %d", __FUNCTION__, mActiveCount);
- int event = RECORD_CONFIG_EVENT_NONE;
-
- if ((oldActiveCount == 0) && (mActiveCount > 0)) {
- event = RECORD_CONFIG_EVENT_START;
- } else if ((oldActiveCount > 0) && (mActiveCount == 0)) {
- event = RECORD_CONFIG_EVENT_STOP;
- }
-
- if (event != RECORD_CONFIG_EVENT_NONE) {
- // Dynamic policy callback:
- // if input maps to a dynamic policy with an activity listener, notify of state change
- if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
- {
- mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
- (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
- }
-
- // Recording configuration callback:
- const AudioIODescriptorInterface* provider = mInfoProvider;
- const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
- AUDIO_CONFIG_BASE_INITIALIZER;
- const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
- AUDIO_PATCH_HANDLE_NONE;
- if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
- mClientInterface->onRecordingConfigurationUpdate(event, &mRecordClientInfo,
- &mConfig, &deviceConfig, patchHandle);
- }
- }
return mActiveCount;
}
@@ -114,27 +82,6 @@
return false;
}
-void AudioSession::setInfoProvider(AudioIODescriptorInterface *provider)
-{
- mInfoProvider = provider;
-}
-
-void AudioSession::onIODescriptorUpdate() const
-{
- if (mActiveCount > 0) {
- // resend the callback after requerying the informations from the info provider
- const AudioIODescriptorInterface* provider = mInfoProvider;
- const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
- AUDIO_CONFIG_BASE_INITIALIZER;
- const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
- AUDIO_PATCH_HANDLE_NONE;
- if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
- mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
- &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
- }
- }
-}
-
status_t AudioSession::dump(int fd, int spaces, int index) const
{
const size_t SIZE = 256;
@@ -169,8 +116,7 @@
}
status_t AudioSessionCollection::addSession(audio_session_t session,
- const sp<AudioSession>& audioSession,
- AudioIODescriptorInterface *provider)
+ const sp<AudioSession>& audioSession)
{
ssize_t index = indexOfKey(session);
@@ -178,7 +124,6 @@
ALOGW("addSession() session %d already in", session);
return ALREADY_EXISTS;
}
- audioSession->setInfoProvider(provider);
add(session, audioSession);
ALOGV("addSession() session %d client %d source %d",
session, audioSession->uid(), audioSession->inputSource());
@@ -194,7 +139,6 @@
return ALREADY_EXISTS;
}
ALOGV("removeSession() session %d", session);
- valueAt(index)->setInfoProvider(NULL);
removeItemsAt(index);
return NO_ERROR;
}
@@ -271,13 +215,6 @@
return source;
}
-void AudioSessionCollection::onIODescriptorUpdate() const
-{
- for (size_t i = 0; i < size(); i++) {
- valueAt(i)->onIODescriptorUpdate();
- }
-}
-
status_t AudioSessionCollection::dump(int fd, int spaces) const
{
const size_t SIZE = 256;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5cdd63a..efc9753 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1679,8 +1679,7 @@
config->channel_mask,
flags,
uid,
- isSoundTrigger,
- policyMix, mpClientInterface);
+ isSoundTrigger);
// FIXME: disable concurrent capture until UI is ready
#if 0
@@ -2007,7 +2006,7 @@
// increment activity count before calling getNewInputDevice() below as only active sessions
// are considered for device selection
- audioSession->changeActiveCount(1);
+ inputDesc->changeRefCount(session, 1);
// Routing?
mInputRoutes.incRouteActivity(session);
@@ -2021,7 +2020,7 @@
status_t status = inputDesc->start();
if (status != NO_ERROR) {
mInputRoutes.decRouteActivity(session);
- audioSession->changeActiveCount(-1);
+ inputDesc->changeRefCount(session, -1);
return status;
}
@@ -2085,7 +2084,7 @@
return INVALID_OPERATION;
}
- audioSession->changeActiveCount(-1);
+ inputDesc->changeRefCount(session, -1);
// Routing?
mInputRoutes.decRouteActivity(session);