audo policy: add effects to record clients

Add list of active effects on input streams and record
clients for further reporting in AudioRecordingConfiguration.

Bug: 111438757
Test: make and dumpsys
Change-Id: I1ae00d2431c80b053f67e2b780f368d5a4822b01
gugelfrei
Eric Laurent 6 years ago
parent 424993f065
commit c241b0dfc4

@ -23,6 +23,7 @@
#include "AudioIODescriptorInterface.h"
#include "AudioPort.h"
#include "ClientDescriptor.h"
#include "EffectDescriptor.h"
namespace android {
@ -62,7 +63,8 @@ public:
bool isSoundTrigger() const;
void setClientActive(const sp<RecordClientDescriptor>& client, bool active);
int32_t activeCount() { return mGlobalActiveCount; }
void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
EffectDescriptorCollection getEnabledEffects() const;
// implementation of AudioIODescriptorInterface
audio_config_base_t getConfig() const override;
audio_patch_handle_t getPatchHandle() const override;
@ -86,6 +88,9 @@ public:
RecordClientVector clientsList(bool activeOnly = false,
audio_source_t source = AUDIO_SOURCE_DEFAULT, bool preferredDeviceOnly = false) const;
// implementation of ClientMapHandler<RecordClientDescriptor>
void addClient(const sp<RecordClientDescriptor> &client) override;
private:
void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);
@ -101,6 +106,7 @@ public:
SortedVector<audio_session_t> mPreemptedSessions;
AudioPolicyClientInterface * const mClientInterface;
int32_t mGlobalActiveCount = 0; // non-client-specific activity ref count
EffectDescriptorCollection mEnabledEffects;
};
class AudioInputCollection :
@ -126,6 +132,8 @@ public:
sp<AudioInputDescriptor> getInputForClient(audio_port_handle_t portId);
void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
void dump(String8 *dst) const;
};

@ -28,6 +28,7 @@
#include <utils/RefBase.h>
#include <utils/String8.h>
#include "AudioPatch.h"
#include "EffectDescriptor.h"
#include "RoutingStrategy.h"
namespace android {
@ -119,13 +120,15 @@ public:
void setAppState(app_state_t appState) { mAppState = appState; }
app_state_t appState() { return mAppState; }
bool isSilenced() const { return mAppState == APP_STATE_IDLE; }
void trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled);
EffectDescriptorCollection getEnabledEffects() const { return mEnabledEffects; }
private:
const audio_source_t mSource;
const audio_input_flags_t mFlags;
const bool mIsSoundTrigger;
app_state_t mAppState;
EffectDescriptorCollection mEnabledEffects;
};
class SourceClientDescriptor: public TrackClientDescriptor
@ -172,7 +175,7 @@ public:
virtual ~ClientMapHandler() = default;
// Track client management
void addClient(const sp<T> &client) {
virtual void addClient(const sp<T> &client) {
const audio_port_handle_t portId = client->portId();
LOG_ALWAYS_FATAL_IF(!mClients.emplace(portId, client).second,
"%s(%d): attempting to add client that already exists", __func__, portId);

@ -25,12 +25,12 @@
namespace android {
class EffectDescriptor : public RefBase
{
public:
void dump(String8 *dst) const;
void dump(String8 *dst, int spaces = 0) const;
int mId; // effect unique ID
int mIo; // io the effect is attached to
routing_strategy mStrategy; // routing strategy the effect is associated to
int mSession; // audio session the effect is on
@ -46,12 +46,14 @@ public:
status_t registerEffect(const effect_descriptor_t *desc, audio_io_handle_t io,
uint32_t strategy, int session, int id);
status_t unregisterEffect(int id);
sp<EffectDescriptor> getEffect(int id) const;
status_t setEffectEnabled(int id, bool enabled);
bool isEffectEnabled(int id) const;
uint32_t getMaxEffectsCpuLoad() const;
uint32_t getMaxEffectsMemory() const;
bool isNonOffloadableEffectEnabled();
bool isNonOffloadableEffectEnabled() const;
void dump(String8 *dst) const;
void dump(String8 *dst, int spaces = 0, bool verbose = true) const;
private:
status_t setEffectEnabled(const sp<EffectDescriptor> &effectDesc, bool enabled);

@ -269,6 +269,16 @@ void AudioInputDescriptor::close()
}
}
void AudioInputDescriptor::addClient(const sp<RecordClientDescriptor> &client) {
ClientMapHandler<RecordClientDescriptor>::addClient(client);
for (size_t i = 0; i < mEnabledEffects.size(); i++) {
if (mEnabledEffects.valueAt(i)->mSession == client->session()) {
client->trackEffectEnabled(mEnabledEffects.valueAt(i), true);
}
}
}
void AudioInputDescriptor::setClientActive(const sp<RecordClientDescriptor>& client, bool active)
{
LOG_ALWAYS_FATAL_IF(getClient(client->portId()) == nullptr,
@ -345,6 +355,33 @@ RecordClientVector AudioInputDescriptor::clientsList(bool activeOnly, audio_sour
return clients;
}
void AudioInputDescriptor::trackEffectEnabled(const sp<EffectDescriptor> &effect,
bool enabled)
{
RecordClientVector clients = getClientsForSession((audio_session_t)effect->mSession);
for (const auto& client : clients) {
client->trackEffectEnabled(effect, enabled);
}
if (enabled) {
mEnabledEffects.replaceValueFor(effect->mId, effect);
} else {
mEnabledEffects.removeItem(effect->mId);
}
}
EffectDescriptorCollection AudioInputDescriptor::getEnabledEffects() const
{
EffectDescriptorCollection enabledEffects;
// report effects for highest priority active source as applied to all clients
RecordClientVector clients =
clientsList(true /*activeOnly*/, source(), false /*preferredDeviceOnly*/);
if (clients.size() > 0) {
enabledEffects = clients[0]->getEnabledEffects();
}
return enabledEffects;
}
void AudioInputDescriptor::dump(String8 *dst) const
{
dst->appendFormat(" ID: %d\n", getId());
@ -352,6 +389,7 @@ void AudioInputDescriptor::dump(String8 *dst) const
dst->appendFormat(" Format: %d\n", mFormat);
dst->appendFormat(" Channels: %08x\n", mChannelMask);
dst->appendFormat(" Devices %08x\n", mDevice);
getEnabledEffects().dump(dst, 1 /*spaces*/, false /*verbose*/);
dst->append(" AudioRecord Clients:\n");
ClientMapHandler<RecordClientDescriptor>::dump(dst);
dst->append("\n");
@ -424,6 +462,17 @@ sp<AudioInputDescriptor> AudioInputCollection::getInputForClient(audio_port_hand
return 0;
}
void AudioInputCollection::trackEffectEnabled(const sp<EffectDescriptor> &effect,
bool enabled)
{
for (size_t i = 0; i < size(); i++) {
sp<AudioInputDescriptor> inputDesc = valueAt(i);
if (inputDesc->mIoHandle == effect->mIo) {
return inputDesc->trackEffectEnabled(effect, enabled);
}
}
}
void AudioInputCollection::dump(String8 *dst) const
{
dst->append("\nInputs dump:\n");

@ -63,10 +63,20 @@ std::string TrackClientDescriptor::toShortString() const
return ss.str();
}
void RecordClientDescriptor::trackEffectEnabled(const sp<EffectDescriptor> &effect, bool enabled)
{
if (enabled) {
mEnabledEffects.replaceValueFor(effect->mId, effect);
} else {
mEnabledEffects.removeItem(effect->mId);
}
}
void RecordClientDescriptor::dump(String8 *dst, int spaces, int index) const
{
ClientDescriptor::dump(dst, spaces, index);
dst->appendFormat("%*s- Source: %d flags: %08x\n", spaces, "", mSource, mFlags);
mEnabledEffects.dump(dst, spaces + 2 /*spaces*/, false /*verbose*/);
}
SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,

@ -22,13 +22,13 @@
namespace android {
void EffectDescriptor::dump(String8 *dst) const
void EffectDescriptor::dump(String8 *dst, int spaces) const
{
dst->appendFormat(" I/O: %d\n", mIo);
dst->appendFormat(" Strategy: %d\n", mStrategy);
dst->appendFormat(" Session: %d\n", mSession);
dst->appendFormat(" Name: %s\n", mDesc.name);
dst->appendFormat(" %s\n", mEnabled ? "Enabled" : "Disabled");
dst->appendFormat("%*sI/O: %d\n", spaces, "", mIo);
dst->appendFormat("%*sStrategy: %d\n", spaces, "", mStrategy);
dst->appendFormat("%*sSession: %d\n", spaces, "", mSession);
dst->appendFormat("%*sName: %s\n", spaces, "", mDesc.name);
dst->appendFormat("%*s%s\n", spaces, "", mEnabled ? "Enabled" : "Disabled");
}
EffectDescriptorCollection::EffectDescriptorCollection() :
@ -45,6 +45,11 @@ status_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *d
int session,
int id)
{
if (getEffect(id) != nullptr) {
ALOGW("%s effect %s already registered", __FUNCTION__, desc->name);
return INVALID_OPERATION;
}
if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
desc->name, desc->memoryUsage);
@ -60,6 +65,7 @@ status_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *d
sp<EffectDescriptor> effectDesc = new EffectDescriptor();
memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t));
effectDesc->mId = id;
effectDesc->mIo = io;
effectDesc->mStrategy = static_cast<routing_strategy>(strategy);
effectDesc->mSession = session;
@ -70,17 +76,22 @@ status_t EffectDescriptorCollection::registerEffect(const effect_descriptor_t *d
return NO_ERROR;
}
status_t EffectDescriptorCollection::unregisterEffect(int id)
sp<EffectDescriptor> EffectDescriptorCollection::getEffect(int id) const
{
ssize_t index = indexOfKey(id);
if (index < 0) {
ALOGW("unregisterEffect() unknown effect ID %d", id);
return INVALID_OPERATION;
return nullptr;
}
return valueAt(index);
}
sp<EffectDescriptor> effectDesc = valueAt(index);
setEffectEnabled(effectDesc, false);
status_t EffectDescriptorCollection::unregisterEffect(int id)
{
sp<EffectDescriptor> effectDesc = getEffect(id);
if (effectDesc == nullptr) {
ALOGW("%s unknown effect ID %d", __FUNCTION__, id);
return INVALID_OPERATION;
}
if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) {
ALOGW("unregisterEffect() memory %d too big for total %d",
@ -107,6 +118,14 @@ status_t EffectDescriptorCollection::setEffectEnabled(int id, bool enabled)
return setEffectEnabled(valueAt(index), enabled);
}
bool EffectDescriptorCollection::isEffectEnabled(int id) const
{
ssize_t index = indexOfKey(id);
if (index < 0) {
return false;
}
return valueAt(index)->mEnabled;
}
status_t EffectDescriptorCollection::setEffectEnabled(const sp<EffectDescriptor> &effectDesc,
bool enabled)
@ -138,7 +157,7 @@ status_t EffectDescriptorCollection::setEffectEnabled(const sp<EffectDescriptor>
return NO_ERROR;
}
bool EffectDescriptorCollection::isNonOffloadableEffectEnabled()
bool EffectDescriptorCollection::isNonOffloadableEffectEnabled() const
{
for (size_t i = 0; i < size(); i++) {
sp<EffectDescriptor> effectDesc = valueAt(i);
@ -162,15 +181,21 @@ uint32_t EffectDescriptorCollection::getMaxEffectsMemory() const
return MAX_EFFECTS_MEMORY;
}
void EffectDescriptorCollection::dump(String8 *dst) const
void EffectDescriptorCollection::dump(String8 *dst, int spaces, bool verbose) const
{
dst->appendFormat(
"\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB, Max memory used: %d KB\n",
(float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory, mTotalEffectsMemoryMaxUsed);
dst->append("Registered effects:\n");
if (verbose) {
dst->appendFormat(
"\n%*sTotal Effects CPU: %f MIPS, "
"Total Effects memory: %d KB, Max memory used: %d KB\n",
spaces, "",
(float) mTotalEffectsCpuLoad / 10,
mTotalEffectsMemory,
mTotalEffectsMemoryMaxUsed);
}
dst->appendFormat("%*sEffects:\n", spaces, "");
for (size_t i = 0; i < size(); i++) {
dst->appendFormat("- Effect %d dump:\n", keyAt(i));
valueAt(i)->dump(dst);
dst->appendFormat("%*s- Effect %d:\n", spaces, "", keyAt(i));
valueAt(i)->dump(dst, spaces + 2);
}
}

@ -2423,6 +2423,33 @@ status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
return mEffects.registerEffect(desc, io, strategy, session, id);
}
status_t AudioPolicyManager::unregisterEffect(int id)
{
if (mEffects.getEffect(id) == nullptr) {
return INVALID_OPERATION;
}
if (mEffects.isEffectEnabled(id)) {
ALOGW("%s effect %d enabled", __FUNCTION__, id);
setEffectEnabled(id, false);
}
return mEffects.unregisterEffect(id);
}
status_t AudioPolicyManager::setEffectEnabled(int id, bool enabled)
{
sp<EffectDescriptor> effect = mEffects.getEffect(id);
if (effect == nullptr) {
return INVALID_OPERATION;
}
status_t status = mEffects.setEffectEnabled(id, enabled);
if (status == NO_ERROR) {
mInputs.trackEffectEnabled(effect, enabled);
}
return status;
}
bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
{
bool active = false;

@ -164,14 +164,8 @@ public:
uint32_t strategy,
int session,
int id);
virtual status_t unregisterEffect(int id)
{
return mEffects.unregisterEffect(id);
}
virtual status_t setEffectEnabled(int id, bool enabled)
{
return mEffects.setEffectEnabled(id, enabled);
}
virtual status_t unregisterEffect(int id);
virtual status_t setEffectEnabled(int id, bool enabled);
virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
// return whether a stream is playing remotely, override to change the definition of

Loading…
Cancel
Save