Merge "Add dynamic source default effects"

gugelfrei
Ari Hausman-Cohen 6 years ago committed by Android (Google) Code Review
commit 2aef6ece23

@ -458,6 +458,38 @@ status_t AudioEffect::newEffectUniqueId(audio_unique_id_t* id)
return NO_ERROR;
}
status_t AudioEffect::addSourceDefaultEffect(const char *typeStr,
const String16& opPackageName,
const char *uuidStr,
int32_t priority,
audio_source_t source,
audio_unique_id_t *id)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
if (typeStr == NULL && uuidStr == NULL) return BAD_VALUE;
// Convert type & uuid from string to effect_uuid_t.
effect_uuid_t type;
if (typeStr != NULL) {
status_t res = stringToGuid(typeStr, &type);
if (res != OK) return res;
} else {
type = *EFFECT_UUID_NULL;
}
effect_uuid_t uuid;
if (uuidStr != NULL) {
status_t res = stringToGuid(uuidStr, &uuid);
if (res != OK) return res;
} else {
uuid = *EFFECT_UUID_NULL;
}
return aps->addSourceDefaultEffect(&type, opPackageName, &uuid, priority, source, id);
}
status_t AudioEffect::addStreamDefaultEffect(const char *typeStr,
const String16& opPackageName,
const char *uuidStr,
@ -490,6 +522,14 @@ status_t AudioEffect::addStreamDefaultEffect(const char *typeStr,
return aps->addStreamDefaultEffect(&type, opPackageName, &uuid, priority, usage, id);
}
status_t AudioEffect::removeSourceDefaultEffect(audio_unique_id_t id)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->removeSourceDefaultEffect(id);
}
status_t AudioEffect::removeStreamDefaultEffect(audio_unique_id_t id)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();

@ -83,7 +83,9 @@ enum {
GET_SURROUND_FORMATS,
SET_SURROUND_FORMAT_ENABLED,
ADD_STREAM_DEFAULT_EFFECT,
REMOVE_STREAM_DEFAULT_EFFECT
REMOVE_STREAM_DEFAULT_EFFECT,
ADD_SOURCE_DEFAULT_EFFECT,
REMOVE_SOURCE_DEFAULT_EFFECT
};
#define MAX_ITEMS_PER_LIST 1024
@ -904,6 +906,41 @@ public:
return static_cast <status_t> (reply.readInt32());
}
virtual status_t addSourceDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_source_t source,
audio_unique_id_t* id)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(type, sizeof(effect_uuid_t));
data.writeString16(opPackageName);
data.write(uuid, sizeof(effect_uuid_t));
data.writeInt32(priority);
data.writeInt32((int32_t) source);
status_t status = remote()->transact(ADD_SOURCE_DEFAULT_EFFECT, data, &reply);
if (status != NO_ERROR) {
return status;
}
status = static_cast <status_t> (reply.readInt32());
*id = reply.readInt32();
return status;
}
virtual status_t removeSourceDefaultEffect(audio_unique_id_t id)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(id);
status_t status = remote()->transact(REMOVE_SOURCE_DEFAULT_EFFECT, data, &reply);
if (status != NO_ERROR) {
return status;
}
return static_cast <status_t> (reply.readInt32());
}
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@ -1636,6 +1673,43 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
}
case ADD_SOURCE_DEFAULT_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
effect_uuid_t type;
status_t status = data.read(&type, sizeof(effect_uuid_t));
if (status != NO_ERROR) {
return status;
}
String16 opPackageName;
status = data.readString16(&opPackageName);
if (status != NO_ERROR) {
return status;
}
effect_uuid_t uuid;
status = data.read(&uuid, sizeof(effect_uuid_t));
if (status != NO_ERROR) {
return status;
}
int32_t priority = data.readInt32();
audio_source_t source = (audio_source_t) data.readInt32();
audio_unique_id_t id = 0;
reply->writeInt32(static_cast <int32_t>(addSourceDefaultEffect(&type,
opPackageName,
&uuid,
priority,
source,
&id)));
reply->writeInt32(id);
return NO_ERROR;
}
case REMOVE_SOURCE_DEFAULT_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_unique_id_t id = static_cast<audio_unique_id_t>(data.readInt32());
reply->writeInt32(static_cast <int32_t>(removeSourceDefaultEffect(id)));
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}

@ -169,6 +169,44 @@ public:
* Static methods for adding/removing system-wide effects.
*/
/*
* Adds an effect to the list of default output effects for a given source type.
*
* If the effect is no longer available when a source of the given type
* is created, the system will continue without adding it.
*
* Parameters:
* typeStr: Type uuid of effect to be a default: can be null if uuidStr is specified.
* This may correspond to the OpenSL ES interface implemented by this effect,
* or could be some vendor-defined type.
* opPackageName: The package name used for app op checks.
* uuidStr: Uuid of effect to be a default: can be null if type is specified.
* This uuid corresponds to a particular implementation of an effect type.
* Note if both uuidStr and typeStr are specified, typeStr is ignored.
* priority: Requested priority for effect control: the priority level corresponds to the
* value of priority parameter: negative values indicate lower priorities, positive
* values higher priorities, 0 being the normal priority.
* source: The source this effect should be a default for.
* id: Address where the system-wide unique id of the default effect should be returned.
*
* Returned status (from utils/Errors.h) can be:
* NO_ERROR successful operation.
* PERMISSION_DENIED could not get AudioFlinger interface
* or caller lacks required permissions.
* NO_INIT effect library failed to initialize.
* BAD_VALUE invalid source, type uuid or implementation uuid.
* NAME_NOT_FOUND no effect with this uuid or type found.
*
* Returned value
* *id: The system-wide unique id of the added default effect.
*/
static status_t addSourceDefaultEffect(const char* typeStr,
const String16& opPackageName,
const char* uuidStr,
int32_t priority,
audio_source_t source,
audio_unique_id_t* id);
/*
* Adds an effect to the list of default output effects for a given stream type.
*
@ -208,6 +246,21 @@ public:
audio_usage_t usage,
audio_unique_id_t* id);
/*
* Removes an effect from the list of default output effects for a given source type.
*
* Parameters:
* id: The system-wide unique id of the effect that should no longer be a default.
*
* Returned status (from utils/Errors.h) can be:
* NO_ERROR successful operation.
* PERMISSION_DENIED could not get AudioFlinger interface
* or caller lacks required permissions.
* NO_INIT effect library failed to initialize.
* BAD_VALUE invalid id.
*/
static status_t removeSourceDefaultEffect(audio_unique_id_t id);
/*
* Removes an effect from the list of default output effects for a given stream type.
*

@ -109,12 +109,19 @@ public:
virtual status_t queryDefaultPreProcessing(audio_session_t audioSession,
effect_descriptor_t *descriptors,
uint32_t *count) = 0;
virtual status_t addSourceDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_source_t source,
audio_unique_id_t* id) = 0;
virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_usage_t usage,
audio_unique_id_t* id) = 0;
virtual status_t removeSourceDefaultEffect(audio_unique_id_t id) = 0;
virtual status_t removeStreamDefaultEffect(audio_unique_id_t id) = 0;
// Check if offload is possible for given format, stream type, sample rate,
// bit rate, duration, video and streaming or offload property is enabled

@ -318,6 +318,74 @@ status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t outpu
return status;
}
status_t AudioPolicyEffects::addSourceDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_source_t source,
audio_unique_id_t* id)
{
if (uuid == NULL || type == NULL) {
ALOGE("addSourceDefaultEffect(): Null uuid or type uuid pointer");
return BAD_VALUE;
}
// HOTWORD and FM_TUNER are two special case sources > MAX.
if (source < AUDIO_SOURCE_DEFAULT ||
(source > AUDIO_SOURCE_MAX &&
source != AUDIO_SOURCE_HOTWORD &&
source != AUDIO_SOURCE_FM_TUNER)) {
ALOGE("addSourceDefaultEffect(): Unsupported source type %d", source);
return BAD_VALUE;
}
// Check that |uuid| or |type| corresponds to an effect on the system.
effect_descriptor_t descriptor = {};
status_t res = AudioEffect::getEffectDescriptor(
uuid, type, EFFECT_FLAG_TYPE_PRE_PROC, &descriptor);
if (res != OK) {
ALOGE("addSourceDefaultEffect(): Failed to find effect descriptor matching uuid/type.");
return res;
}
// Only pre-processing effects can be added dynamically as source defaults.
if ((descriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) {
ALOGE("addSourceDefaultEffect(): Desired effect cannot be attached "
"as a source default effect.");
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
// Find the EffectDescVector for the given source type, or create a new one if necessary.
ssize_t index = mInputSources.indexOfKey(source);
EffectDescVector *desc = NULL;
if (index < 0) {
// No effects for this source type yet.
desc = new EffectDescVector();
mInputSources.add(source, desc);
} else {
desc = mInputSources.valueAt(index);
}
// Create a new effect and add it to the vector.
res = AudioEffect::newEffectUniqueId(id);
if (res != OK) {
ALOGE("addSourceDefaultEffect(): failed to get new unique id.");
return res;
}
EffectDesc *effect = new EffectDesc(
descriptor.name, *type, opPackageName, *uuid, priority, *id);
desc->mEffects.add(effect);
// TODO(b/71813697): Support setting params as well.
// TODO(b/71814300): Retroactively attach to any existing sources of the given type.
// This requires tracking the source type of each session id in addition to what is
// already being tracked.
return NO_ERROR;
}
status_t AudioPolicyEffects::addStreamDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
@ -384,6 +452,37 @@ status_t AudioPolicyEffects::addStreamDefaultEffect(const effect_uuid_t *type,
return NO_ERROR;
}
status_t AudioPolicyEffects::removeSourceDefaultEffect(audio_unique_id_t id)
{
if (id == AUDIO_UNIQUE_ID_ALLOCATE) {
// ALLOCATE is not a unique identifier, but rather a reserved value indicating
// a real id has not been assigned. For default effects, this value is only used
// by system-owned defaults from the loaded config, which cannot be removed.
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
// Check each source type.
size_t numSources = mInputSources.size();
for (size_t i = 0; i < numSources; ++i) {
// Check each effect for each source.
EffectDescVector* descVector = mInputSources[i];
for (auto desc = descVector->mEffects.begin(); desc != descVector->mEffects.end(); ++desc) {
if ((*desc)->mId == id) {
// Found it!
// TODO(b/71814300): Remove from any sources the effect was attached to.
descVector->mEffects.erase(desc);
// Handles are unique; there can only be one match, so return early.
return NO_ERROR;
}
}
}
// Effect wasn't found, so it's been trivially removed successfully.
return NO_ERROR;
}
status_t AudioPolicyEffects::removeStreamDefaultEffect(audio_unique_id_t id)
{
if (id == AUDIO_UNIQUE_ID_ALLOCATE) {

@ -81,7 +81,15 @@ public:
audio_stream_type_t stream,
audio_session_t audioSession);
// Add the effect to the list of default effects for streams of type |stream|.
// Add the effect to the list of default effects for sources of type |source|.
status_t addSourceDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_source_t source,
audio_unique_id_t* id);
// Add the effect to the list of default effects for streams of a given usage.
status_t addStreamDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
@ -89,6 +97,9 @@ public:
audio_usage_t usage,
audio_unique_id_t* id);
// Remove the default source effect from wherever it's attached.
status_t removeSourceDefaultEffect(audio_unique_id_t id);
// Remove the default stream effect from wherever it's attached.
status_t removeStreamDefaultEffect(audio_unique_id_t id);

@ -829,67 +829,96 @@ bool AudioPolicyService::isSourceActive(audio_source_t source) const
return mAudioPolicyManager->isSourceActive(source);
}
status_t AudioPolicyService::queryDefaultPreProcessing(audio_session_t audioSession,
effect_descriptor_t *descriptors,
uint32_t *count)
status_t AudioPolicyService::getAudioPolicyEffects(sp<AudioPolicyEffects>& audioPolicyEffects)
{
if (mAudioPolicyManager == NULL) {
*count = 0;
return NO_INIT;
}
sp<AudioPolicyEffects>audioPolicyEffects;
{
Mutex::Autolock _l(mLock);
audioPolicyEffects = mAudioPolicyEffects;
}
if (audioPolicyEffects == 0) {
*count = 0;
return NO_INIT;
}
return OK;
}
status_t AudioPolicyService::queryDefaultPreProcessing(audio_session_t audioSession,
effect_descriptor_t *descriptors,
uint32_t *count)
{
sp<AudioPolicyEffects>audioPolicyEffects;
status_t status = getAudioPolicyEffects(audioPolicyEffects);
if (status != OK) {
*count = 0;
return status;
}
return audioPolicyEffects->queryDefaultInputEffects(
(audio_session_t)audioSession, descriptors, count);
}
status_t AudioPolicyService::addStreamDefaultEffect(const effect_uuid_t *type,
status_t AudioPolicyService::addSourceDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_usage_t usage,
audio_source_t source,
audio_unique_id_t* id)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
sp<AudioPolicyEffects>audioPolicyEffects;
status_t status = getAudioPolicyEffects(audioPolicyEffects);
if (status != OK) {
return status;
}
if (!modifyDefaultAudioEffectsAllowed()) {
return PERMISSION_DENIED;
}
return audioPolicyEffects->addSourceDefaultEffect(
type, opPackageName, uuid, priority, source, id);
}
status_t AudioPolicyService::addStreamDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_usage_t usage,
audio_unique_id_t* id)
{
sp<AudioPolicyEffects>audioPolicyEffects;
{
Mutex::Autolock _l(mLock);
audioPolicyEffects = mAudioPolicyEffects;
status_t status = getAudioPolicyEffects(audioPolicyEffects);
if (status != OK) {
return status;
}
if (audioPolicyEffects == 0) {
return NO_INIT;
if (!modifyDefaultAudioEffectsAllowed()) {
return PERMISSION_DENIED;
}
return audioPolicyEffects->addStreamDefaultEffect(
type, opPackageName, uuid, priority, usage, id);
}
status_t AudioPolicyService::removeStreamDefaultEffect(audio_unique_id_t id)
status_t AudioPolicyService::removeSourceDefaultEffect(audio_unique_id_t id)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
sp<AudioPolicyEffects>audioPolicyEffects;
status_t status = getAudioPolicyEffects(audioPolicyEffects);
if (status != OK) {
return status;
}
if (!modifyDefaultAudioEffectsAllowed()) {
return PERMISSION_DENIED;
}
return audioPolicyEffects->removeSourceDefaultEffect(id);
}
status_t AudioPolicyService::removeStreamDefaultEffect(audio_unique_id_t id)
{
sp<AudioPolicyEffects>audioPolicyEffects;
{
Mutex::Autolock _l(mLock);
audioPolicyEffects = mAudioPolicyEffects;
status_t status = getAudioPolicyEffects(audioPolicyEffects);
if (status != OK) {
return status;
}
if (audioPolicyEffects == 0) {
return NO_INIT;
if (!modifyDefaultAudioEffectsAllowed()) {
return PERMISSION_DENIED;
}
return audioPolicyEffects->removeStreamDefaultEffect(id);
}

@ -126,12 +126,19 @@ public:
virtual status_t queryDefaultPreProcessing(audio_session_t audioSession,
effect_descriptor_t *descriptors,
uint32_t *count);
virtual status_t addSourceDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_source_t source,
audio_unique_id_t* id);
virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
audio_usage_t usage,
audio_unique_id_t* id);
virtual status_t removeSourceDefaultEffect(audio_unique_id_t id);
virtual status_t removeStreamDefaultEffect(audio_unique_id_t id);
virtual status_t onTransact(
@ -259,6 +266,8 @@ private:
std::string getDeviceTypeStrForPortId(audio_port_handle_t portId);
status_t getAudioPolicyEffects(sp<AudioPolicyEffects>& audioPolicyEffects);
// If recording we need to make sure the UID is allowed to do that. If the UID is idle
// then it cannot record and gets buffers with zeros - silence. As soon as the UID
// transitions to an active state we will start reporting buffers with data. This approach

Loading…
Cancel
Save