audiopolicy: add Volume for attribute and callback native APIs

Change-Id: I259de42452d2802aa8dbd553f56040dea6995a93
Signed-off-by: François Gaffie <francois.gaffie@renault.com>

Bug: 124767636
Test: make
gugelfrei
François Gaffie 6 years ago committed by Eric Laurent
parent a6d44870d8
commit cfe173220a

@ -792,6 +792,7 @@ const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service()
int64_t token = IPCThreadState::self()->clearCallingIdentity();
ap->registerClient(apc);
ap->setAudioPortCallbacksEnabled(apc->isAudioPortCbEnabled());
ap->setAudioVolumeGroupCallbacksEnabled(apc->isAudioVolumeGroupCbEnabled());
IPCThreadState::self()->restoreCallingIdentity(token);
}
@ -987,6 +988,38 @@ status_t AudioSystem::getStreamVolumeIndex(audio_stream_type_t stream,
return aps->getStreamVolumeIndex(stream, index, device);
}
status_t AudioSystem::setVolumeIndexForAttributes(const audio_attributes_t &attr,
int index,
audio_devices_t device)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->setVolumeIndexForAttributes(attr, index, device);
}
status_t AudioSystem::getVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index,
audio_devices_t device)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->getVolumeIndexForAttributes(attr, index, device);
}
status_t AudioSystem::getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->getMaxVolumeIndexForAttributes(attr, index);
}
status_t AudioSystem::getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->getMinVolumeIndexForAttributes(attr, index);
}
uint32_t AudioSystem::getStrategyForStream(audio_stream_type_t stream)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
@ -1190,6 +1223,38 @@ status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callb
return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
}
status_t AudioSystem::addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
Mutex::Autolock _l(gLockAPS);
if (gAudioPolicyServiceClient == 0) {
return NO_INIT;
}
int ret = gAudioPolicyServiceClient->addAudioVolumeGroupCallback(callback);
if (ret == 1) {
aps->setAudioVolumeGroupCallbacksEnabled(true);
}
return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
}
status_t AudioSystem::removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
Mutex::Autolock _l(gLockAPS);
if (gAudioPolicyServiceClient == 0) {
return NO_INIT;
}
int ret = gAudioPolicyServiceClient->removeAudioVolumeGroupCallback(callback);
if (ret == 0) {
aps->setAudioVolumeGroupCallbacksEnabled(false);
}
return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
}
status_t AudioSystem::addAudioDeviceCallback(
const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
{
@ -1498,6 +1563,47 @@ void AudioSystem::AudioPolicyServiceClient::onAudioPatchListUpdate()
}
}
// ----------------------------------------------------------------------------
int AudioSystem::AudioPolicyServiceClient::addAudioVolumeGroupCallback(
const sp<AudioVolumeGroupCallback>& callback)
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
if (mAudioVolumeGroupCallback[i] == callback) {
return -1;
}
}
mAudioVolumeGroupCallback.add(callback);
return mAudioVolumeGroupCallback.size();
}
int AudioSystem::AudioPolicyServiceClient::removeAudioVolumeGroupCallback(
const sp<AudioVolumeGroupCallback>& callback)
{
Mutex::Autolock _l(mLock);
size_t i;
for (i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
if (mAudioVolumeGroupCallback[i] == callback) {
break;
}
}
if (i == mAudioVolumeGroupCallback.size()) {
return -1;
}
mAudioVolumeGroupCallback.removeAt(i);
return mAudioVolumeGroupCallback.size();
}
void AudioSystem::AudioPolicyServiceClient::onAudioVolumeGroupChanged(volume_group_t group,
int flags)
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
mAudioVolumeGroupCallback[i]->onAudioVolumeGroupChanged(group, flags);
}
}
// ----------------------------------------------------------------------------
void AudioSystem::AudioPolicyServiceClient::onDynamicPolicyMixStateUpdate(
String8 regId, int32_t state)
{
@ -1541,6 +1647,9 @@ void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __
for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
mAudioPortCallbacks[i]->onServiceDied();
}
for (size_t i = 0; i < mAudioVolumeGroupCallback.size(); i++) {
mAudioVolumeGroupCallback[i]->onServiceDied();
}
}
{
Mutex::Autolock _l(gLockAPS);

@ -51,6 +51,10 @@ enum {
INIT_STREAM_VOLUME,
SET_STREAM_VOLUME,
GET_STREAM_VOLUME,
SET_VOLUME_ATTRIBUTES,
GET_VOLUME_ATTRIBUTES,
GET_MIN_VOLUME_FOR_ATTRIBUTES,
GET_MAX_VOLUME_FOR_ATTRIBUTES,
GET_STRATEGY_FOR_STREAM,
GET_OUTPUT_FOR_EFFECT,
REGISTER_EFFECT,
@ -78,6 +82,7 @@ enum {
START_AUDIO_SOURCE,
STOP_AUDIO_SOURCE,
SET_AUDIO_PORT_CALLBACK_ENABLED,
SET_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED,
SET_MASTER_MONO,
GET_MASTER_MONO,
GET_STREAM_VOLUME_DB,
@ -417,6 +422,70 @@ public:
return static_cast <status_t> (reply.readInt32());
}
virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr, int index,
audio_devices_t device)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(&attr, sizeof(audio_attributes_t));
data.writeInt32(index);
data.writeInt32(static_cast <uint32_t>(device));
status_t status = remote()->transact(SET_VOLUME_ATTRIBUTES, data, &reply);
if (status != NO_ERROR) {
return status;
}
return static_cast <status_t> (reply.readInt32());
}
virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr, int &index,
audio_devices_t device)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(&attr, sizeof(audio_attributes_t));
data.writeInt32(static_cast <uint32_t>(device));
status_t status = remote()->transact(GET_VOLUME_ATTRIBUTES, data, &reply);
if (status != NO_ERROR) {
return status;
}
status = static_cast <status_t> (reply.readInt32());
if (status != NO_ERROR) {
return status;
}
index = reply.readInt32();
return NO_ERROR;
}
virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(&attr, sizeof(audio_attributes_t));
status_t status = remote()->transact(GET_MIN_VOLUME_FOR_ATTRIBUTES, data, &reply);
if (status != NO_ERROR) {
return status;
}
status = static_cast <status_t> (reply.readInt32());
if (status != NO_ERROR) {
return status;
}
index = reply.readInt32();
return NO_ERROR;
}
virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.write(&attr, sizeof(audio_attributes_t));
status_t status = remote()->transact(GET_MAX_VOLUME_FOR_ATTRIBUTES, data, &reply);
if (status != NO_ERROR) {
return status;
}
status = static_cast <status_t> (reply.readInt32());
if (status != NO_ERROR) {
return status;
}
index = reply.readInt32();
return NO_ERROR;
}
virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
{
Parcel data, reply;
@ -694,6 +763,14 @@ public:
remote()->transact(SET_AUDIO_PORT_CALLBACK_ENABLED, data, &reply);
}
virtual void setAudioVolumeGroupCallbacksEnabled(bool enabled)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(enabled ? 1 : 0);
remote()->transact(SET_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED, data, &reply);
}
virtual status_t acquireSoundTriggerSession(audio_session_t *session,
audio_io_handle_t *ioHandle,
audio_devices_t *device)
@ -1492,6 +1569,73 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
} break;
case SET_VOLUME_ATTRIBUTES: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_attributes_t attributes = {};
status_t status = data.read(&attributes, sizeof(audio_attributes_t));
if (status != NO_ERROR) {
return status;
}
int index = data.readInt32();
audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
reply->writeInt32(static_cast <uint32_t>(setVolumeIndexForAttributes(attributes,
index, device)));
return NO_ERROR;
} break;
case GET_VOLUME_ATTRIBUTES: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_attributes_t attributes = {};
status_t status = data.read(&attributes, sizeof(audio_attributes_t));
if (status != NO_ERROR) {
return status;
}
audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
int index = 0;
status = getVolumeIndexForAttributes(attributes, index, device);
reply->writeInt32(static_cast <uint32_t>(status));
if (status == NO_ERROR) {
reply->writeInt32(index);
}
return NO_ERROR;
} break;
case GET_MIN_VOLUME_FOR_ATTRIBUTES: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_attributes_t attributes = {};
status_t status = data.read(&attributes, sizeof(audio_attributes_t));
if (status != NO_ERROR) {
return status;
}
int index = 0;
status = getMinVolumeIndexForAttributes(attributes, index);
reply->writeInt32(static_cast <uint32_t>(status));
if (status == NO_ERROR) {
reply->writeInt32(index);
}
return NO_ERROR;
} break;
case GET_MAX_VOLUME_FOR_ATTRIBUTES: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_attributes_t attributes = {};
status_t status = data.read(&attributes, sizeof(audio_attributes_t));
if (status != NO_ERROR) {
return status;
}
int index = 0;
status = getMaxVolumeIndexForAttributes(attributes, index);
reply->writeInt32(static_cast <uint32_t>(status));
if (status == NO_ERROR) {
reply->writeInt32(index);
}
return NO_ERROR;
} break;
case GET_DEVICES_FOR_STREAM: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_stream_type_t stream =
@ -1740,6 +1884,12 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
} break;
case SET_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
setAudioVolumeGroupCallbacksEnabled(data.readInt32() == 1);
return NO_ERROR;
} break;
case ACQUIRE_SOUNDTRIGGER_SESSION: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>(

@ -31,7 +31,8 @@ enum {
PORT_LIST_UPDATE = IBinder::FIRST_CALL_TRANSACTION,
PATCH_LIST_UPDATE,
MIX_STATE_UPDATE,
RECORDING_CONFIGURATION_UPDATE
RECORDING_CONFIGURATION_UPDATE,
VOLUME_GROUP_CHANGED,
};
// ----------------------------------------------------------------------
@ -108,6 +109,15 @@ public:
remote()->transact(PATCH_LIST_UPDATE, data, &reply, IBinder::FLAG_ONEWAY);
}
void onAudioVolumeGroupChanged(volume_group_t group, int flags)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyServiceClient::getInterfaceDescriptor());
data.writeUint32(group);
data.writeInt32(flags);
remote()->transact(VOLUME_GROUP_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
}
void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state)
{
Parcel data, reply;
@ -157,6 +167,13 @@ status_t BnAudioPolicyServiceClient::onTransact(
onAudioPatchListUpdate();
return NO_ERROR;
} break;
case VOLUME_GROUP_CHANGED: {
CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
volume_group_t group = static_cast<volume_group_t>(data.readUint32());
int flags = data.readInt32();
onAudioVolumeGroupChanged(group, flags);
return NO_ERROR;
} break;
case MIX_STATE_UPDATE: {
CHECK_INTERFACE(IAudioPolicyServiceClient, data, reply);
String8 regId = data.readString8();

@ -264,6 +264,17 @@ public:
int *index,
audio_devices_t device);
static status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
int index,
audio_devices_t device);
static status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index,
audio_devices_t device);
static status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
static status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
static uint32_t getStrategyForStream(audio_stream_type_t stream);
static audio_devices_t getDevicesForStream(audio_stream_type_t stream);
@ -381,6 +392,21 @@ public:
// ----------------------------------------------------------------------------
class AudioVolumeGroupCallback : public RefBase
{
public:
AudioVolumeGroupCallback() {}
virtual ~AudioVolumeGroupCallback() {}
virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags) = 0;
virtual void onServiceDied() = 0;
};
static status_t addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
static status_t removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
class AudioPortCallback : public RefBase
{
public:
@ -513,12 +539,17 @@ private:
int removeAudioPortCallback(const sp<AudioPortCallback>& callback);
bool isAudioPortCbEnabled() const { return (mAudioPortCallbacks.size() != 0); }
int addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
int removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback);
bool isAudioVolumeGroupCbEnabled() const { return (mAudioVolumeGroupCallback.size() != 0); }
// DeathRecipient
virtual void binderDied(const wp<IBinder>& who);
// IAudioPolicyServiceClient
virtual void onAudioPortListUpdate();
virtual void onAudioPatchListUpdate();
virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags);
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
virtual void onRecordingConfigurationUpdate(int event,
const record_client_info_t *clientInfo,
@ -532,6 +563,7 @@ private:
private:
Mutex mLock;
Vector <sp <AudioPortCallback> > mAudioPortCallbacks;
Vector <sp <AudioVolumeGroupCallback> > mAudioVolumeGroupCallback;
};
static audio_io_handle_t getOutput(audio_stream_type_t stream);

@ -93,6 +93,17 @@ public:
virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
int *index,
audio_devices_t device) = 0;
virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
int index,
audio_devices_t device) = 0;
virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index,
audio_devices_t device) = 0;
virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index) = 0;
virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index) = 0;
virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0;
virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream) = 0;
virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc) = 0;
@ -160,6 +171,8 @@ public:
virtual void setAudioPortCallbacksEnabled(bool enabled) = 0;
virtual void setAudioVolumeGroupCallbacksEnabled(bool enabled) = 0;
virtual status_t acquireSoundTriggerSession(audio_session_t *session,
audio_io_handle_t *ioHandle,
audio_devices_t *device) = 0;

@ -23,6 +23,8 @@
#include <binder/IInterface.h>
#include <system/audio.h>
#include <system/audio_effect.h>
#include <media/AudioPolicy.h>
#include <media/AudioVolumeGroup.h>
namespace android {
@ -45,6 +47,8 @@ class IAudioPolicyServiceClient : public IInterface
public:
DECLARE_META_INTERFACE(AudioPolicyServiceClient);
// Notifies a change of volume group
virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags) = 0;
// Notifies a change of audio port configuration.
virtual void onAudioPortListUpdate() = 0;
// Notifies a change of audio patch configuration.

@ -159,6 +159,19 @@ public:
int *index,
audio_devices_t device) = 0;
virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
int index,
audio_devices_t device) = 0;
virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index,
audio_devices_t device) = 0;
virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index) = 0;
virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index) = 0;
// return the strategy corresponding to a given stream type
virtual uint32_t getStrategyForStream(audio_stream_type_t stream) = 0;
@ -347,6 +360,8 @@ public:
virtual void onAudioPatchListUpdate() = 0;
virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags) = 0;
virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) = 0;
virtual void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state) = 0;

@ -2498,6 +2498,107 @@ status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
return NO_ERROR;
}
status_t AudioPolicyManager::setVolumeIndexForAttributes(const audio_attributes_t &attr,
int index,
audio_devices_t device)
{
// Get Volume group matching the Audio Attributes
auto volumeGroup = mEngine->getVolumeGroupForAttributes(attr);
if (volumeGroup == VOLUME_GROUP_NONE) {
ALOGD("%s: could not find group matching with %s", __FUNCTION__, toString(attr).c_str());
return BAD_VALUE;
}
ALOGD("%s: FOUND group %d matching with %s", __FUNCTION__, volumeGroup, toString(attr).c_str());
return setVolumeGroupIndex(getVolumeCurves(attr), volumeGroup, index, device, attr);
}
status_t AudioPolicyManager::setVolumeGroupIndex(IVolumeCurves &curves, volume_group_t group,
int index,
audio_devices_t device,
const audio_attributes_t /*attributes*/)
{
ALOGVV("%s: group=%d", __func__, group);
status_t status = NO_ERROR;
setVolumeCurveIndex(group, index, device, curves);
// update volume on all outputs and streams matching the following:
// - The requested stream (or a stream matching for volume control) is active on the output
// - The device (or devices) selected by the engine for this stream includes
// the requested device
// - For non default requested device, currently selected device on the output is either the
// requested device or one of the devices selected by the engine for this stream
// - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
// no specific device volume value exists for currently selected device.
// @TODO
mpClientInterface->onAudioVolumeGroupChanged(group, 0 /*flags*/);
return status;
}
status_t AudioPolicyManager::setVolumeCurveIndex(volume_group_t volumeGroup,
int index,
audio_devices_t device,
IVolumeCurves &volumeCurves)
{
// VOICE_CALL stream has minVolumeIndex > 0 but can be muted directly by an
// app that has MODIFY_PHONE_STATE permission.
// If voice is member of the volume group, it will contaminate all the member of this group
auto streams = mEngine->getStreamTypesForVolumeGroup(volumeGroup);
if (((index < volumeCurves.getVolumeIndexMin()) && !(hasVoiceStream(streams) && index == 0)) ||
(index > volumeCurves.getVolumeIndexMax())) {
ALOGD("%s: wrong index %d min=%d max=%d", __FUNCTION__, index,
volumeCurves.getVolumeIndexMin(), volumeCurves.getVolumeIndexMax());
return BAD_VALUE;
}
if (!audio_is_output_device(device)) {
return BAD_VALUE;
}
// Force max volume if stream cannot be muted
if (!volumeCurves.canBeMuted()) index = volumeCurves.getVolumeIndexMax();
ALOGD("%s device %08x, index %d", __FUNCTION__ , device, index);
volumeCurves.addCurrentVolumeIndex(device, index);
return NO_ERROR;
}
status_t AudioPolicyManager::getVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index,
audio_devices_t device)
{
// if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device selected for this
// stream by the engine.
if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
device = mEngine->getOutputDevicesForAttributes(attr, nullptr, true /*fromCache*/).types();
}
return getVolumeIndex(getVolumeCurves(attr), index, device);
}
status_t AudioPolicyManager::getVolumeIndex(const IVolumeCurves &curves,
int &index,
audio_devices_t device) const
{
if (!audio_is_output_device(device)) {
return BAD_VALUE;
}
device = Volume::getDeviceForVolume(device);
index = curves.getVolumeIndex(device);
ALOGV("%s: device %08x index %d", __FUNCTION__, device, index);
return NO_ERROR;
}
status_t AudioPolicyManager::getMinVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index)
{
index = getVolumeCurves(attr).getVolumeIndexMin();
return NO_ERROR;
}
status_t AudioPolicyManager::getMaxVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index)
{
index = getVolumeCurves(attr).getVolumeIndexMax();
return NO_ERROR;
}
audio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()
{
// select one output among several suitable for global effects.

@ -161,6 +161,27 @@ public:
int *index,
audio_devices_t device);
virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
int index,
audio_devices_t device);
virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index,
audio_devices_t device);
virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index);
status_t setVolumeGroupIndex(IVolumeCurves &volumeCurves, volume_group_t group, int index,
audio_devices_t device, const audio_attributes_t attributes);
status_t setVolumeCurveIndex(volume_group_t volumeGroup,
int index,
audio_devices_t device,
IVolumeCurves &volumeCurves);
status_t getVolumeIndex(const IVolumeCurves &curves, int &index,
audio_devices_t device) const;
// return the strategy corresponding to a given stream type
virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
{

@ -222,6 +222,12 @@ void AudioPolicyService::AudioPolicyClient::onRecordingConfigurationUpdate(
clientConfig, clientEffects, deviceConfig, effects, patchHandle, source);
}
void AudioPolicyService::AudioPolicyClient::onAudioVolumeGroupChanged(volume_group_t group,
int flags)
{
mAudioPolicyService->onAudioVolumeGroupChanged(group, flags);
}
audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId(audio_unique_id_use_t use)
{
return AudioSystem::newAudioUniqueId(use);

@ -689,6 +689,53 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
device);
}
status_t AudioPolicyService::setVolumeIndexForAttributes(const audio_attributes_t &attributes,
int index, audio_devices_t device)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->setVolumeIndexForAttributes(attributes, index, device);
}
status_t AudioPolicyService::getVolumeIndexForAttributes(const audio_attributes_t &attributes,
int &index, audio_devices_t device)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->getVolumeIndexForAttributes(attributes, index, device);
}
status_t AudioPolicyService::getMinVolumeIndexForAttributes(const audio_attributes_t &attributes,
int &index)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->getMinVolumeIndexForAttributes(attributes, index);
}
status_t AudioPolicyService::getMaxVolumeIndexForAttributes(const audio_attributes_t &attributes,
int &index)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->getMaxVolumeIndexForAttributes(attributes, index);
}
uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {

@ -150,6 +150,20 @@ void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
mNotificationClients.valueFor(token)->setAudioPortCallbacksEnabled(enabled);
}
void AudioPolicyService::setAudioVolumeGroupCallbacksEnabled(bool enabled)
{
Mutex::Autolock _l(mNotificationClientsLock);
uid_t uid = IPCThreadState::self()->getCallingUid();
pid_t pid = IPCThreadState::self()->getCallingPid();
int64_t token = ((int64_t)uid<<32) | pid;
if (mNotificationClients.indexOfKey(token) < 0) {
return;
}
mNotificationClients.valueFor(token)->setAudioVolumeGroupCallbacksEnabled(enabled);
}
// removeNotificationClient() is called when the client process dies.
void AudioPolicyService::removeNotificationClient(uid_t uid, pid_t pid)
{
@ -200,6 +214,19 @@ void AudioPolicyService::doOnAudioPatchListUpdate()
}
}
void AudioPolicyService::onAudioVolumeGroupChanged(volume_group_t group, int flags)
{
mOutputCommandThread->changeAudioVolumeGroupCommand(group, flags);
}
void AudioPolicyService::doOnAudioVolumeGroupChanged(volume_group_t group, int flags)
{
Mutex::Autolock _l(mNotificationClientsLock);
for (size_t i = 0; i < mNotificationClients.size(); i++) {
mNotificationClients.valueAt(i)->onAudioVolumeGroupChanged(group, flags);
}
}
void AudioPolicyService::onDynamicPolicyMixStateUpdate(const String8& regId, int32_t state)
{
ALOGV("AudioPolicyService::onDynamicPolicyMixStateUpdate(%s, %d)",
@ -270,7 +297,7 @@ AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyS
uid_t uid,
pid_t pid)
: mService(service), mUid(uid), mPid(pid), mAudioPolicyServiceClient(client),
mAudioPortCallbacksEnabled(false)
mAudioPortCallbacksEnabled(false), mAudioVolumeGroupCallbacksEnabled(false)
{
}
@ -301,6 +328,15 @@ void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
}
}
void AudioPolicyService::NotificationClient::onAudioVolumeGroupChanged(volume_group_t group,
int flags)
{
if (mAudioPolicyServiceClient != 0 && mAudioVolumeGroupCallbacksEnabled) {
mAudioPolicyServiceClient->onAudioVolumeGroupChanged(group, flags);
}
}
void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
const String8& regId, int32_t state)
{
@ -330,6 +366,10 @@ void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool e
mAudioPortCallbacksEnabled = enabled;
}
void AudioPolicyService::NotificationClient::setAudioVolumeGroupCallbacksEnabled(bool enabled)
{
mAudioVolumeGroupCallbacksEnabled = enabled;
}
void AudioPolicyService::binderDied(const wp<IBinder>& who) {
ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
@ -1058,6 +1098,18 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
svc->doOnAudioPatchListUpdate();
mLock.lock();
}break;
case CHANGED_AUDIOVOLUMEGROUP: {
AudioVolumeGroupData *data =
static_cast<AudioVolumeGroupData *>(command->mParam.get());
ALOGV("AudioCommandThread() processing update audio volume group");
svc = mService.promote();
if (svc == 0) {
break;
}
mLock.unlock();
svc->doOnAudioVolumeGroupChanged(data->mGroup, data->mFlags);
mLock.lock();
}break;
case SET_AUDIOPORT_CONFIG: {
SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
ALOGV("AudioCommandThread() processing set port config");
@ -1302,6 +1354,19 @@ void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
sendCommand(command);
}
void AudioPolicyService::AudioCommandThread::changeAudioVolumeGroupCommand(volume_group_t group,
int flags)
{
sp<AudioCommand>command = new AudioCommand();
command->mCommand = CHANGED_AUDIOVOLUMEGROUP;
AudioVolumeGroupData *data= new AudioVolumeGroupData();
data->mGroup = group;
data->mFlags = flags;
command->mParam = data;
ALOGV("AudioCommandThread() adding audio volume group changed");
sendCommand(command);
}
status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
const struct audio_port_config *config, int delayMs)
{

@ -111,6 +111,17 @@ public:
int *index,
audio_devices_t device);
virtual status_t setVolumeIndexForAttributes(const audio_attributes_t &attr,
int index,
audio_devices_t device);
virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index,
audio_devices_t device);
virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index);
virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr,
int &index);
virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
@ -192,6 +203,8 @@ public:
virtual void setAudioPortCallbacksEnabled(bool enabled);
virtual void setAudioVolumeGroupCallbacksEnabled(bool enabled);
virtual status_t acquireSoundTriggerSession(audio_session_t *session,
audio_io_handle_t *ioHandle,
audio_devices_t *device);
@ -275,6 +288,9 @@ public:
audio_patch_handle_t patchHandle,
audio_source_t source);
void onAudioVolumeGroupChanged(volume_group_t group, int flags);
void doOnAudioVolumeGroupChanged(volume_group_t group, int flags);
private:
AudioPolicyService() ANDROID_API;
virtual ~AudioPolicyService();
@ -404,6 +420,7 @@ private:
RELEASE_AUDIO_PATCH,
UPDATE_AUDIOPORT_LIST,
UPDATE_AUDIOPATCH_LIST,
CHANGED_AUDIOVOLUMEGROUP,
SET_AUDIOPORT_CONFIG,
DYN_POLICY_MIX_STATE_UPDATE,
RECORDING_CONFIGURATION_UPDATE
@ -435,6 +452,7 @@ private:
int delayMs);
void updateAudioPortListCommand();
void updateAudioPatchListCommand();
void changeAudioVolumeGroupCommand(volume_group_t group, int flags);
status_t setAudioPortConfigCommand(const struct audio_port_config *config,
int delayMs);
void dynamicPolicyMixStateUpdateCommand(const String8& regId,
@ -516,6 +534,12 @@ private:
audio_patch_handle_t mHandle;
};
class AudioVolumeGroupData : public AudioCommandData {
public:
volume_group_t mGroup;
int mFlags;
};
class SetAudioPortConfigData : public AudioCommandData {
public:
struct audio_port_config mConfig;
@ -648,6 +672,8 @@ private:
audio_patch_handle_t patchHandle,
audio_source_t source);
virtual void onAudioVolumeGroupChanged(volume_group_t group, int flags);
virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use);
private:
@ -666,6 +692,7 @@ private:
void onAudioPatchListUpdate();
void onDynamicPolicyMixStateUpdate(const String8& regId,
int32_t state);
void onAudioVolumeGroupChanged(volume_group_t group, int flags);
void onRecordingConfigurationUpdate(
int event,
const record_client_info_t *clientInfo,
@ -676,6 +703,7 @@ private:
audio_patch_handle_t patchHandle,
audio_source_t source);
void setAudioPortCallbacksEnabled(bool enabled);
void setAudioVolumeGroupCallbacksEnabled(bool enabled);
uid_t uid() {
return mUid;
@ -693,6 +721,7 @@ private:
const pid_t mPid;
const sp<IAudioPolicyServiceClient> mAudioPolicyServiceClient;
bool mAudioPortCallbacksEnabled;
bool mAudioVolumeGroupCallbacksEnabled;
};
class AudioClient : public virtual RefBase {

@ -73,6 +73,7 @@ public:
int /*delayMs*/) override { return NO_INIT; }
void onAudioPortListUpdate() override { }
void onAudioPatchListUpdate() override { }
void onAudioVolumeGroupChanged(volume_group_t /*group*/, int /*flags*/) override { }
audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t /*use*/) override { return 0; }
void onDynamicPolicyMixStateUpdate(String8 /*regId*/, int32_t /*state*/) override { }
void onRecordingConfigurationUpdate(int event __unused,

Loading…
Cancel
Save