audiopolicy: Remove raw pointer references to AudioMix

AudioInputDescriptor and AudioOutputDescriptor used to reference
AudioMix instances using a raw pointer. This isn't safe as AudioMix
was owned by AudioPolicyMix, which is not referenced by descriptors.

Change AudioMix* pointers in Audio{Input|Output}Descriptor to
wp<AudioPolicyMix> which reflects their relationship correctly.

To ensure that code does not operate on AudioMix instances
independently from AudioPolicyMix, and to avoid introducing
a lot of getter / setter methods into AudioPolicyMix, make
the latter to inherit AudioMix. This makes sense because
AudioPolicyMix is essentially a ref-counted version of AudioMix.

Bug: 124899895
Test: build and sanity check on crosshatch,
      build crosshatch with USE_CONFIGURABLE_AUDIO_POLICY := 1
Change-Id: Ic508caedefe721ed7e7ba6ee3e9175ba9e8dc23a
gugelfrei
Mikhail Naganov 5 years ago
parent efde55813c
commit bfac583d00

@ -29,7 +29,7 @@
namespace android {
class AudioMix;
class AudioPolicyMix;
class AudioPolicyClientInterface;
// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
@ -53,7 +53,7 @@ public:
void dump(String8 *dst) const override;
audio_io_handle_t mIoHandle = AUDIO_IO_HANDLE_NONE; // input handle
AudioMix *mPolicyMix = nullptr; // non NULL when used by a dynamic policy
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
const sp<IOProfile> mProfile; // I/O profile this output derives from
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,

@ -34,7 +34,7 @@
namespace android {
class IOProfile;
class AudioMix;
class AudioPolicyMix;
class AudioPolicyClientInterface;
class ActivityTracking
@ -281,7 +281,7 @@ public:
}
DeviceVector mDevices; /**< current devices this output is routed to */
AudioMix *mPolicyMix = nullptr; // non NULL when used by a dynamic policy
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
protected:
const sp<AudioPort> mPort;

@ -31,24 +31,19 @@ namespace android {
/**
* custom mix entry in mPolicyMixes
*/
class AudioPolicyMix : public RefBase {
class AudioPolicyMix : public AudioMix, public RefBase {
public:
AudioPolicyMix() {}
AudioPolicyMix(const AudioMix &mix) : AudioMix(mix) {}
AudioPolicyMix(const AudioPolicyMix&) = delete;
AudioPolicyMix& operator=(const AudioPolicyMix&) = delete;
const sp<SwAudioOutputDescriptor> &getOutput() const;
void setOutput(sp<SwAudioOutputDescriptor> &output);
void clearOutput();
android::AudioMix *getMix();
void setMix(const AudioMix &mix);
const sp<SwAudioOutputDescriptor> &getOutput() const { return mOutput; }
void setOutput(const sp<SwAudioOutputDescriptor> &output) { mOutput = output; }
void clearOutput() { mOutput.clear(); }
void dump(String8 *dst, int spaces, int index) const;
private:
AudioMix mMix; // Audio policy mix descriptor
sp<SwAudioOutputDescriptor> mOutput; // Corresponding output stream
};
@ -77,21 +72,19 @@ public:
sp<DeviceDescriptor> getDeviceAndMixForInputSource(audio_source_t inputSource,
const DeviceVector &availableDeviceTypes,
AudioMix **policyMix) const;
sp<AudioPolicyMix> *policyMix) const;
/**
* @brief try to find a matching mix for a given output descriptor and returns the associated
* output device.
* @param output to be considered
* @param availableOutputDevices list of output devices currently reachable
* @param policyMix to be returned if any mix matching ouput descriptor
* @return device selected from the mix attached to the output, null pointer otherwise
*/
sp<DeviceDescriptor> getDeviceAndMixForOutput(const sp<SwAudioOutputDescriptor> &output,
const DeviceVector &availableOutputDevices,
AudioMix **policyMix = nullptr);
const DeviceVector &availableOutputDevices);
status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
status_t getInputMixForAttr(audio_attributes_t attr, sp<AudioPolicyMix> *policyMix);
status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices);
status_t removeUidDeviceAffinities(uid_t uid);

@ -22,6 +22,7 @@
#include <AudioPolicyInterface.h>
#include "AudioInputDescriptor.h"
#include "AudioGain.h"
#include "AudioPolicyMix.h"
#include "HwModule.h"
namespace android {
@ -308,16 +309,17 @@ void AudioInputDescriptor::setClientActive(const sp<RecordClientDescriptor>& cli
const int delta = active ? 1 : -1;
mGlobalActiveCount += delta;
sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
if ((oldGlobalActiveCount == 0) && (mGlobalActiveCount > 0)) {
if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
{
mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
MIX_STATE_MIXING);
}
} else if ((oldGlobalActiveCount > 0) && (mGlobalActiveCount == 0)) {
if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
{
mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
MIX_STATE_IDLE);
}
}

@ -19,6 +19,7 @@
#include <AudioPolicyInterface.h>
#include "AudioOutputDescriptor.h"
#include "AudioPolicyMix.h"
#include "IOProfile.h"
#include "AudioGain.h"
#include "Volume.h"
@ -111,9 +112,10 @@ void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& cli
}
mGlobalActiveCount += delta;
if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) {
mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE);
}
}

@ -27,51 +27,26 @@
namespace android {
void AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output)
{
mOutput = output;
}
const sp<SwAudioOutputDescriptor> &AudioPolicyMix::getOutput() const
{
return mOutput;
}
void AudioPolicyMix::clearOutput()
{
mOutput.clear();
}
void AudioPolicyMix::setMix(const AudioMix &mix)
{
mMix = mix;
}
android::AudioMix *AudioPolicyMix::getMix()
{
return &mMix;
}
void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
{
dst->appendFormat("%*sAudio Policy Mix %d:\n", spaces, "", index + 1);
std::string mixTypeLiteral;
if (!MixTypeConverter::toString(mMix.mMixType, mixTypeLiteral)) {
ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMix.mMixType);
if (!MixTypeConverter::toString(mMixType, mixTypeLiteral)) {
ALOGE("%s: failed to convert mix type %d", __FUNCTION__, mMixType);
return;
}
dst->appendFormat("%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
std::string routeFlagLiteral;
RouteFlagTypeConverter::maskToString(mMix.mRouteFlags, routeFlagLiteral);
RouteFlagTypeConverter::maskToString(mRouteFlags, routeFlagLiteral);
dst->appendFormat("%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
dst->appendFormat("%*s- device type: %s\n", spaces, "", toString(mMix.mDeviceType).c_str());
dst->appendFormat("%*s- device type: %s\n", spaces, "", toString(mDeviceType).c_str());
dst->appendFormat("%*s- device address: %s\n", spaces, "", mMix.mDeviceAddress.string());
dst->appendFormat("%*s- device address: %s\n", spaces, "", mDeviceAddress.string());
int indexCriterion = 0;
for (const auto &criterion : mMix.mCriteria) {
for (const auto &criterion : mCriteria) {
dst->appendFormat("%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
std::string usageLiteral;
@ -81,7 +56,7 @@ void AudioPolicyMix::dump(String8 *dst, int spaces, int index) const
}
dst->appendFormat("%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
if (mMix.mMixType == MIX_TYPE_RECORDERS) {
if (mMixType == MIX_TYPE_RECORDERS) {
std::string sourceLiteral;
if (!SourceTypeConverter::toString(criterion.mValue.mSource, sourceLiteral)) {
ALOGE("%s: failed to convert source %d", __FUNCTION__, criterion.mValue.mSource);
@ -109,12 +84,11 @@ status_t AudioPolicyMixCollection::registerMix(const String8& address, AudioMix
ALOGE("registerPolicyMixes(): mix for address %s already registered", address.string());
return BAD_VALUE;
}
sp<AudioPolicyMix> policyMix = new AudioPolicyMix();
policyMix->setMix(mix);
sp<AudioPolicyMix> policyMix = new AudioPolicyMix(mix);
add(address, policyMix);
if (desc != 0) {
desc->mPolicyMix = policyMix->getMix();
desc->mPolicyMix = policyMix;
policyMix->setOutput(desc);
}
return NO_ERROR;
@ -168,15 +142,14 @@ status_t AudioPolicyMixCollection::getOutputForAttr(
continue;
}
AudioMix *mix = policyMix->getMix();
const bool primaryOutputMix = !is_mix_loopback_render(mix->mRouteFlags);
const bool primaryOutputMix = !is_mix_loopback_render(policyMix->mRouteFlags);
if (primaryOutputMix && primaryDesc != 0) {
ALOGV("%s: Skiping %zu: Primary output already found", __func__, i);
continue; // Primary output already found
}
switch (mixMatch(mix, i, attributes, uid)) {
switch (mixMatch(policyMix.get(), i, attributes, uid)) {
case MixMatchStatus::INVALID_MIX: return BAD_VALUE; // TODO: Do we really want to abort?
case MixMatchStatus::NO_MATCH:
ALOGV("%s: Mix %zu: does not match", __func__, i);
@ -184,7 +157,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr(
case MixMatchStatus::MATCH:;
}
policyDesc->mPolicyMix = mix;
policyDesc->mPolicyMix = policyMix;
if (primaryOutputMix) {
primaryDesc = policyDesc;
ALOGV("%s: Mix %zu: set primary desc", __func__, i);
@ -327,17 +300,13 @@ AudioPolicyMixCollection::MixMatchStatus AudioPolicyMixCollection::mixMatch(
sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForOutput(
const sp<SwAudioOutputDescriptor> &output,
const DeviceVector &availableOutputDevices,
AudioMix **policyMix)
const DeviceVector &availableOutputDevices)
{
for (size_t i = 0; i < size(); i++) {
if (valueAt(i)->getOutput() == output) {
AudioMix *mix = valueAt(i)->getMix();
if (policyMix != nullptr)
*policyMix = mix;
// This Desc is involved in a Mix, which has the highest prio
audio_devices_t deviceType = mix->mDeviceType;
String8 address = mix->mDeviceAddress;
audio_devices_t deviceType = valueAt(i)->mDeviceType;
String8 address = valueAt(i)->mDeviceAddress;
ALOGV("%s: device (0x%x, addr=%s) forced by mix",
__FUNCTION__, deviceType, address.c_str());
return availableOutputDevices.getDevice(deviceType, address, AUDIO_FORMAT_DEFAULT);
@ -347,10 +316,12 @@ sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForOutput(
}
sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
audio_source_t inputSource, const DeviceVector &availDevices, AudioMix **policyMix) const
audio_source_t inputSource,
const DeviceVector &availDevices,
sp<AudioPolicyMix> *policyMix) const
{
for (size_t i = 0; i < size(); i++) {
AudioMix *mix = valueAt(i)->getMix();
AudioPolicyMix *mix = valueAt(i).get();
if (mix->mMixType != MIX_TYPE_RECORDERS) {
continue;
}
@ -365,7 +336,7 @@ sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
auto mixDevice =
availDevices.getDevice(device, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
if (mixDevice != nullptr) {
if (policyMix != NULL) {
if (policyMix != nullptr) {
*policyMix = mix;
}
return mixDevice;
@ -377,7 +348,8 @@ sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
return nullptr;
}
status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix)
status_t AudioPolicyMixCollection::getInputMixForAttr(
audio_attributes_t attr, sp<AudioPolicyMix> *policyMix)
{
if (strncmp(attr.tags, "addr=", strlen("addr=")) != 0) {
return BAD_VALUE;
@ -387,9 +359,8 @@ status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, A
#ifdef LOG_NDEBUG
ALOGV("getInputMixForAttr looking for address %s\n mixes available:", address.string());
for (size_t i = 0; i < size(); i++) {
sp<AudioPolicyMix> policyMix = valueAt(i);
const AudioMix *mix = policyMix->getMix();
ALOGV("\tmix %zu address=%s", i, mix->mDeviceAddress.string());
sp<AudioPolicyMix> audioPolicyMix = valueAt(i);
ALOGV("\tmix %zu address=%s", i, audioPolicyMix->mDeviceAddress.string());
}
#endif
@ -399,13 +370,14 @@ status_t AudioPolicyMixCollection::getInputMixForAttr(audio_attributes_t attr, A
return BAD_VALUE;
}
sp<AudioPolicyMix> audioPolicyMix = valueAt(index);
AudioMix *mix = audioPolicyMix->getMix();
if (mix->mMixType != MIX_TYPE_PLAYERS) {
if (audioPolicyMix->mMixType != MIX_TYPE_PLAYERS) {
ALOGW("getInputMixForAttr() bad policy mix type for address %s", address.string());
return BAD_VALUE;
}
*policyMix = mix;
if (policyMix != nullptr) {
*policyMix = audioPolicyMix;
}
return NO_ERROR;
}
@ -416,7 +388,7 @@ status_t AudioPolicyMixCollection::setUidDeviceAffinities(uid_t uid,
// for each player mix: add a rule to match or exclude the uid based on the device
for (size_t i = 0; i < size(); i++) {
const AudioMix *mix = valueAt(i)->getMix();
const AudioPolicyMix *mix = valueAt(i).get();
if (mix->mMixType != MIX_TYPE_PLAYERS) {
continue;
}
@ -445,7 +417,7 @@ status_t AudioPolicyMixCollection::removeUidDeviceAffinities(uid_t uid) {
// for each player mix: remove existing rules that match or exclude this uid
for (size_t i = 0; i < size(); i++) {
bool foundUidRule = false;
const AudioMix *mix = valueAt(i)->getMix();
const AudioPolicyMix *mix = valueAt(i).get();
if (mix->mMixType != MIX_TYPE_PLAYERS) {
continue;
}
@ -473,7 +445,7 @@ status_t AudioPolicyMixCollection::getDevicesForUid(uid_t uid,
// for each player mix: find rules that don't exclude this uid, and add the device to the list
for (size_t i = 0; i < size(); i++) {
bool ruleAllowsUid = true;
const AudioMix *mix = valueAt(i)->getMix();
const AudioPolicyMix *mix = valueAt(i).get();
if (mix->mMixType != MIX_TYPE_PLAYERS) {
continue;
}

@ -169,7 +169,7 @@ public:
* @return selected input device for the audio attributes, may be null if error.
*/
virtual sp<DeviceDescriptor> getInputDeviceForAttributes(
const audio_attributes_t &attr, AudioMix **mix = nullptr) const = 0;
const audio_attributes_t &attr, sp<AudioPolicyMix> *mix = nullptr) const = 0;
/**
* Get the legacy stream type for a given audio attributes.

@ -295,7 +295,7 @@ DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool
}
sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
AudioMix **mix) const
sp<AudioPolicyMix> *mix) const
{
const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();

@ -62,7 +62,7 @@ public:
bool fromCache = false) const override;
sp<DeviceDescriptor> getInputDeviceForAttributes(
const audio_attributes_t &attr, AudioMix **mix = nullptr) const override;
const audio_attributes_t &attr, sp<AudioPolicyMix> *mix = nullptr) const override;
void updateDeviceSelectionCache() override;

@ -727,7 +727,7 @@ DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool
}
sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
AudioMix **mix) const
sp<AudioPolicyMix> *mix) const
{
const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();

@ -66,7 +66,7 @@ private:
bool fromCache = false) const override;
sp<DeviceDescriptor> getInputDeviceForAttributes(
const audio_attributes_t &attr, AudioMix **mix = nullptr) const override;
const audio_attributes_t &attr, sp<AudioPolicyMix> *mix = nullptr) const override;
void updateDeviceSelectionCache() override;

@ -217,10 +217,11 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
&& strncmp(device_address, "0", AUDIO_DEVICE_MAX_ADDRESS_LEN) != 0) {
for (audio_io_handle_t output : outputs) {
sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(output);
if (desc->mPolicyMix != nullptr
&& desc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS
sp<AudioPolicyMix> policyMix = desc->mPolicyMix.promote();
if (policyMix != nullptr
&& policyMix->mMixType == MIX_TYPE_RECORDERS
&& strncmp(device_address,
desc->mPolicyMix->mDeviceAddress.string(),
policyMix->mDeviceAddress.string(),
AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
doCheckForDeviceAndOutputChanges = false;
break;
@ -968,7 +969,7 @@ status_t AudioPolicyManager::getOutputForAttrInt(
}
if (usePrimaryOutputFromPolicyMixes) {
*output = policyDesc->mIoHandle;
AudioMix *mix = policyDesc->mPolicyMix;
sp<AudioPolicyMix> mix = policyDesc->mPolicyMix.promote();
sp<DeviceDescriptor> deviceDesc =
mAvailableOutputDevices.getDevice(mix->mDeviceType,
mix->mDeviceAddress,
@ -1602,10 +1603,9 @@ status_t AudioPolicyManager::startSource(const sp<SwAudioOutputDescriptor>& outp
(outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
DeviceVector devices;
AudioMix *policyMix = NULL;
sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
const char *address = NULL;
if (outputDesc->mPolicyMix != NULL) {
policyMix = outputDesc->mPolicyMix;
if (policyMix != NULL) {
audio_devices_t newDeviceType;
address = policyMix->mDeviceAddress.string();
if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
@ -1775,12 +1775,13 @@ status_t AudioPolicyManager::stopSource(const sp<SwAudioOutputDescriptor>& outpu
if (outputDesc->getActivityCount(clientVolSrc) == 1) {
// Automatically disable the remote submix input when output is stopped on a
// re routing mix of type MIX_TYPE_RECORDERS
sp<AudioPolicyMix> policyMix = outputDesc->mPolicyMix.promote();
if (audio_is_remote_submix_device(outputDesc->devices().types()) &&
outputDesc->mPolicyMix != NULL &&
outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
policyMix != NULL &&
policyMix->mMixType == MIX_TYPE_RECORDERS) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
outputDesc->mPolicyMix->mDeviceAddress,
policyMix->mDeviceAddress,
"remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
@ -1895,7 +1896,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
status_t status = NO_ERROR;
audio_source_t halInputSource;
audio_attributes_t attributes = *attr;
AudioMix *policyMix = NULL;
sp<AudioPolicyMix> policyMix;
sp<DeviceDescriptor> device;
sp<AudioInputDescriptor> inputDesc;
sp<RecordClientDescriptor> clientDesc;
@ -1992,7 +1993,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
status = BAD_VALUE;
goto error;
}
if (policyMix != nullptr) {
if (policyMix) {
ALOG_ASSERT(policyMix->mMixType == MIX_TYPE_RECORDERS, "Invalid Mix Type");
// there is an external policy, but this input is attached to a mix of recorders,
// meaning it receives audio injected into the framework, so the recorder doesn't
@ -2044,7 +2045,7 @@ audio_io_handle_t AudioPolicyManager::getInputForDevice(const sp<DeviceDescripto
const audio_attributes_t &attributes,
const audio_config_base_t *config,
audio_input_flags_t flags,
AudioMix *policyMix)
const sp<AudioPolicyMix> &policyMix)
{
audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
audio_source_t halInputSource = attributes.source;
@ -2204,10 +2205,11 @@ status_t AudioPolicyManager::startInput(audio_port_handle_t portId)
setInputDevice(input, device, true /* force */);
if (inputDesc->activeCount() == 1) {
sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
&& ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
if ((policyMix != NULL)
&& ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
MIX_STATE_MIXING);
}
@ -2222,10 +2224,10 @@ status_t AudioPolicyManager::startInput(audio_port_handle_t portId)
// For remote submix (a virtual device), we open only one input per capture request.
if (audio_is_remote_submix_device(inputDesc->getDeviceType())) {
String8 address = String8("");
if (inputDesc->mPolicyMix == NULL) {
if (policyMix == NULL) {
address = String8("0");
} else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
address = inputDesc->mPolicyMix->mDeviceAddress;
} else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
address = policyMix->mDeviceAddress;
}
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
@ -2262,10 +2264,11 @@ status_t AudioPolicyManager::stopInput(audio_port_handle_t portId)
if (inputDesc->isActive()) {
setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
} else {
sp<AudioPolicyMix> policyMix = inputDesc->mPolicyMix.promote();
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
&& ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
if ((policyMix != NULL)
&& ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
mpClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
MIX_STATE_IDLE);
}
@ -2273,10 +2276,10 @@ status_t AudioPolicyManager::stopInput(audio_port_handle_t portId)
// used by a policy mix of type MIX_TYPE_RECORDERS
if (audio_is_remote_submix_device(inputDesc->getDeviceType())) {
String8 address = String8("");
if (inputDesc->mPolicyMix == NULL) {
if (policyMix == NULL) {
address = String8("0");
} else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
address = inputDesc->mPolicyMix->mDeviceAddress;
} else if (policyMix->mMixType == MIX_TYPE_PLAYERS) {
address = policyMix->mDeviceAddress;
}
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
@ -4582,7 +4585,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
sp<AudioPolicyMix> policyMix;
if (mPolicyMixes.getAudioPolicyMix(address, policyMix) == NO_ERROR) {
policyMix->setOutput(desc);
desc->mPolicyMix = policyMix->getMix();
desc->mPolicyMix = policyMix;
} else {
ALOGW("checkOutputsForDevice() cannot find policy for address %s",
address.string());

@ -799,7 +799,7 @@ private:
const audio_attributes_t &attributes,
const audio_config_base_t *config,
audio_input_flags_t flags,
AudioMix *policyMix);
const sp<AudioPolicyMix> &policyMix);
// event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
// returns 0 if no mute/unmute event happened, the largest latency of the device where

Loading…
Cancel
Save