Skip to content
Permalink
Browse files

DO NOT MERGE: audiopolicy: Remove raw pointer references to AudioMix

AudioInputDescriptor, AudioOutputDescriptor, and AudioSession 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 and
AudioSession 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 marlin,
      build marlin with USE_CONFIGURABLE_AUDIO_POLICY := 1
Merged-In: Ic508caedefe721ed7e7ba6ee3e9175ba9e8dc23a
Change-Id: Ic508caedefe721ed7e7ba6ee3e9175ba9e8dc23a
(cherry picked from commit a306e2a)
  • Loading branch information...
Mikhail Naganov android-build-team Robot
Mikhail Naganov authored and android-build-team Robot committed Mar 6, 2019
1 parent 127949a commit 97fa3267af541d6c5fe0cafb53592056b4c10c2e
@@ -27,7 +27,7 @@
namespace android {

class IOProfile;
class AudioMix;
class AudioPolicyMix;

// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
// and keep track of the usage of this input.
@@ -44,7 +44,7 @@ class AudioInputDescriptor: public AudioPortConfig, public AudioSessionInfoProvi

audio_io_handle_t mIoHandle; // input handle
audio_devices_t mDevice; // current device this input is routed to
AudioMix *mPolicyMix; // 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,
@@ -29,7 +29,7 @@
namespace android {

class IOProfile;
class AudioMix;
class AudioPolicyMix;
class AudioPolicyClientInterface;
class DeviceDescriptor;

@@ -141,7 +141,7 @@ class SwAudioOutputDescriptor: public AudioOutputDescriptor
audio_io_handle_t mIoHandle; // output handle
uint32_t mLatency; //
audio_output_flags_t mFlags; //
AudioMix *mPolicyMix; // non NULL when used by a dynamic policy
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
sp<SwAudioOutputDescriptor> mOutput1; // used by duplicated outputs: first output
sp<SwAudioOutputDescriptor> mOutput2; // used by duplicated outputs: second output
uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
@@ -29,24 +29,21 @@ class SwAudioOutputDescriptor;
/**
* custom mix entry in mPolicyMixes
*/
class AudioPolicyMix : public RefBase {
class AudioPolicyMix : public AudioMix, public RefBase {
public:
AudioPolicyMix() {}
AudioPolicyMix(const 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(AudioMix &mix);

status_t dump(int fd, int spaces, int index) const;

private:
AudioMix mMix; // Audio policy mix descriptor
sp<SwAudioOutputDescriptor> mOutput; // Corresponding output stream
};

@@ -76,9 +73,9 @@ class AudioPolicyMixCollection : public DefaultKeyedVector<String8, sp<AudioPoli

audio_devices_t getDeviceAndMixForInputSource(audio_source_t inputSource,
audio_devices_t availableDeviceTypes,
AudioMix **policyMix);
sp<AudioPolicyMix> *policyMix);

status_t getInputMixForAttr(audio_attributes_t attr, AudioMix **policyMix);
status_t getInputMixForAttr(audio_attributes_t attr, sp<AudioPolicyMix> *policyMix);

status_t dump(int fd) const;
};
@@ -28,6 +28,7 @@
namespace android {

class AudioPolicyClientInterface;
class AudioPolicyMix;

class AudioSession : public RefBase, public AudioSessionInfoUpdateListener
{
@@ -40,7 +41,7 @@ class AudioSession : public RefBase, public AudioSessionInfoUpdateListener
audio_input_flags_t flags,
uid_t uid,
bool isSoundTrigger,
AudioMix* policyMix,
const sp<AudioPolicyMix> &policyMix,
AudioPolicyClientInterface *clientInterface);

status_t dump(int fd, int spaces, int index) const;
@@ -75,7 +76,7 @@ class AudioSession : public RefBase, public AudioSessionInfoUpdateListener
bool mSilenced;
uint32_t mOpenCount;
uint32_t mActiveCount;
AudioMix* mPolicyMix; // non NULL when used by a dynamic policy
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
AudioPolicyClientInterface* mClientInterface;
const AudioSessionInfoProvider* mInfoProvider;
};
@@ -21,6 +21,7 @@
#include "AudioInputDescriptor.h"
#include "IOProfile.h"
#include "AudioGain.h"
#include "AudioPolicyMix.h"
#include "HwModule.h"
#include <media/AudioPolicy.h>
#include <policy.h>
@@ -19,6 +19,7 @@

#include <AudioPolicyInterface.h>
#include "AudioOutputDescriptor.h"
#include "AudioPolicyMix.h"
#include "IOProfile.h"
#include "AudioGain.h"
#include "Volume.h"
@@ -307,17 +308,18 @@ void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
} else {
mGlobalRefCount += delta;
}
sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 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 ((oldGlobalRefCount > 0) && (mGlobalRefCount == 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);
}
}
@@ -27,6 +27,10 @@

namespace android {

AudioPolicyMix::AudioPolicyMix(const AudioMix &mix) : AudioMix(mix)
{
}

void AudioPolicyMix::setOutput(sp<SwAudioOutputDescriptor> &output)
{
mOutput = output;
@@ -42,16 +46,6 @@ void AudioPolicyMix::clearOutput()
mOutput.clear();
}

void AudioPolicyMix::setMix(AudioMix &mix)
{
mMix = mix;
}

android::AudioMix *AudioPolicyMix::getMix()
{
return &mMix;
}

status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
{
const size_t SIZE = 256;
@@ -61,25 +55,25 @@ status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
snprintf(buffer, SIZE, "%*sAudio Policy Mix %d:\n", spaces, "", index+1);
result.append(buffer);
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 BAD_VALUE;
}
snprintf(buffer, SIZE, "%*s- mix type: %s\n", spaces, "", mixTypeLiteral.c_str());
result.append(buffer);
std::string routeFlagLiteral;
RouteFlagTypeConverter::maskToString(mMix.mRouteFlags, routeFlagLiteral);
RouteFlagTypeConverter::maskToString(mRouteFlags, routeFlagLiteral);
snprintf(buffer, SIZE, "%*s- Route Flags: %s\n", spaces, "", routeFlagLiteral.c_str());
result.append(buffer);
std::string deviceLiteral;
deviceToString(mMix.mDeviceType, deviceLiteral);
deviceToString(mDeviceType, deviceLiteral);
snprintf(buffer, SIZE, "%*s- device type: %s\n", spaces, "", deviceLiteral.c_str());
result.append(buffer);
snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mMix.mDeviceAddress.string());
snprintf(buffer, SIZE, "%*s- device address: %s\n", spaces, "", mDeviceAddress.string());
result.append(buffer);

int indexCriterion = 0;
for (const auto &criterion : mMix.mCriteria) {
for (const auto &criterion : mCriteria) {
snprintf(buffer, SIZE, "%*s- Criterion %d:\n", spaces + 2, "", indexCriterion++);
result.append(buffer);
std::string usageLiteral;
@@ -89,7 +83,7 @@ status_t AudioPolicyMix::dump(int fd, int spaces, int index) const
}
snprintf(buffer, SIZE, "%*s- Usage:%s\n", spaces + 4, "", usageLiteral.c_str());
result.append(buffer);
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);
@@ -120,12 +114,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;
@@ -171,8 +164,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
ALOGV("getOutputForAttr() querying %zu mixes:", size());
desc = 0;
for (size_t i = 0; i < size(); i++) {
sp<AudioPolicyMix> policyMix = valueAt(i);
AudioMix *mix = policyMix->getMix();
sp<AudioPolicyMix> mix = valueAt(i);

if (mix->mMixType == MIX_TYPE_PLAYERS) {
// TODO if adding more player rules (currently only 2), make rule handling "generic"
@@ -269,7 +261,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
(hasUidExcludeRules && uidExclusionFound) ||
(hasUidMatchRules && !uidMatchFound))) {
ALOGV("\tgetOutputForAttr will use mix %zu", i);
desc = policyMix->getOutput();
desc = mix->getOutput();
}

} else if (mix->mMixType == MIX_TYPE_RECORDERS) {
@@ -278,7 +270,7 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
strncmp(attributes.tags + strlen("addr="),
mix->mDeviceAddress.string(),
AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - strlen("addr=") - 1) == 0) {
desc = policyMix->getOutput();
desc = mix->getOutput();
}
}
if (desc != 0) {
@@ -289,12 +281,13 @@ status_t AudioPolicyMixCollection::getOutputForAttr(audio_attributes_t attribute
return BAD_VALUE;
}

audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_source_t inputSource,
audio_devices_t availDevices,
AudioMix **policyMix)
audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(
audio_source_t inputSource,
audio_devices_t availDevices,
sp<AudioPolicyMix> *policyMix)
{
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;
@@ -317,7 +310,8 @@ audio_devices_t AudioPolicyMixCollection::getDeviceAndMixForInputSource(audio_so
return AUDIO_DEVICE_NONE;
}

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;
@@ -327,8 +321,7 @@ 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);
AudioMix *mix = policyMix->getMix();
sp<AudioPolicyMix> mix = valueAt(i);
ALOGV("\tmix %zu address=%s", i, mix->mDeviceAddress.string());
}
#endif
@@ -339,13 +332,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;
}

@@ -19,6 +19,7 @@

#include <AudioPolicyInterface.h>
#include "policy.h"
#include "AudioPolicyMix.h"
#include "AudioSession.h"
#include "AudioGain.h"
#include "TypeConverter.h"
@@ -36,7 +37,7 @@ AudioSession::AudioSession(audio_session_t session,
audio_input_flags_t flags,
uid_t uid,
bool isSoundTrigger,
AudioMix* policyMix,
const sp<AudioPolicyMix> &policyMix,
AudioPolicyClientInterface *clientInterface) :
mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
@@ -79,9 +80,10 @@ uint32_t AudioSession::changeActiveCount(int delta)
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))
sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
{
mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
(event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
}

0 comments on commit 97fa326

Please sign in to comment.
You can’t perform that action at this time.