audio policy: refactor HW audio sources

Refactor management of hardware audio sources to make use of
ClientDescriptor class:
- HW sources are now tracked by port ID and not audio patch handle.
- startAudioSource() and stopAudioSource() APIs are updated to use
audio_port_handle_t as source identifier.
- AudioSourceDescriptor class is deleted and replaced by
SourceClientDescriptor class deriving from TrackClientDescriptor

Test: make.
Change-Id: Ie418b566519a591f036b538a77319f8e30aa99a8
gugelfrei
Eric Laurent 6 years ago
parent f344afa981
commit 3e6c7e1591

@ -1238,18 +1238,18 @@ status_t AudioSystem::registerPolicyMixes(const Vector<AudioMix>& mixes, bool re
status_t AudioSystem::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle)
audio_port_handle_t *portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->startAudioSource(source, attributes, handle);
return aps->startAudioSource(source, attributes, portId);
}
status_t AudioSystem::stopAudioSource(audio_patch_handle_t handle)
status_t AudioSystem::stopAudioSource(audio_port_handle_t portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->stopAudioSource(handle);
return aps->stopAudioSource(portId);
}
status_t AudioSystem::setMasterMono(bool mono)

@ -740,11 +740,11 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle)
audio_port_handle_t *portId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
if (source == NULL || attributes == NULL || handle == NULL) {
if (source == NULL || attributes == NULL || portId == NULL) {
return BAD_VALUE;
}
data.write(source, sizeof(struct audio_port_config));
@ -757,15 +757,15 @@ public:
if (status != NO_ERROR) {
return status;
}
*handle = (audio_patch_handle_t)reply.readInt32();
*portId = (audio_port_handle_t)reply.readInt32();
return status;
}
virtual status_t stopAudioSource(audio_patch_handle_t handle)
virtual status_t stopAudioSource(audio_port_handle_t portId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(handle);
data.writeInt32(portId);
status_t status = remote()->transact(STOP_AUDIO_SOURCE, data, &reply);
if (status != NO_ERROR) {
return status;
@ -1472,17 +1472,17 @@ status_t BnAudioPolicyService::onTransact(
audio_attributes_t attributes = {};
data.read(&attributes, sizeof(audio_attributes_t));
sanetizeAudioAttributes(&attributes);
audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
status_t status = startAudioSource(&source, &attributes, &handle);
audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE;
status_t status = startAudioSource(&source, &attributes, &portId);
reply->writeInt32(status);
reply->writeInt32(handle);
reply->writeInt32(portId);
return NO_ERROR;
} break;
case STOP_AUDIO_SOURCE: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_patch_handle_t handle = (audio_patch_handle_t) data.readInt32();
status_t status = stopAudioSource(handle);
audio_port_handle_t portId = (audio_port_handle_t) data.readInt32();
status_t status = stopAudioSource(portId);
reply->writeInt32(status);
return NO_ERROR;
} break;

@ -322,9 +322,9 @@ public:
static status_t registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration);
static status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle);
static status_t stopAudioSource(audio_patch_handle_t handle);
const audio_attributes_t *attributes,
audio_port_handle_t *portId);
static status_t stopAudioSource(audio_port_handle_t portId);
static status_t setMasterMono(bool mono);
static status_t getMasterMono(bool *mono);

@ -153,8 +153,8 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle) = 0;
virtual status_t stopAudioSource(audio_patch_handle_t handle) = 0;
audio_port_handle_t *portId) = 0;
virtual status_t stopAudioSource(audio_port_handle_t portId) = 0;
virtual status_t setMasterMono(bool mono) = 0;
virtual status_t getMasterMono(bool *mono) = 0;

@ -226,9 +226,9 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle,
audio_port_handle_t *portId,
uid_t uid) = 0;
virtual status_t stopAudioSource(audio_patch_handle_t handle) = 0;
virtual status_t stopAudioSource(audio_port_handle_t portId) = 0;
virtual status_t setMasterMono(bool mono) = 0;
virtual status_t getMasterMono(bool *mono) = 0;

@ -18,7 +18,6 @@ LOCAL_SRC_FILES:= \
src/EffectDescriptor.cpp \
src/SoundTriggerSession.cpp \
src/SessionRoute.cpp \
src/AudioSourceDescriptor.cpp \
src/VolumeCurve.cpp \
src/TypeConverter.cpp \
src/AudioSession.cpp \

@ -24,7 +24,6 @@
#include <RoutingStrategy.h>
#include "AudioIODescriptorInterface.h"
#include "AudioPort.h"
#include "AudioSourceDescriptor.h"
#include "ClientDescriptor.h"
namespace android {
@ -159,7 +158,7 @@ public:
class HwAudioOutputDescriptor: public AudioOutputDescriptor
{
public:
HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
AudioPolicyClientInterface *clientInterface);
virtual ~HwAudioOutputDescriptor() {}
@ -176,7 +175,7 @@ public:
const struct audio_port_config *srcConfig = NULL) const;
virtual void toAudioPort(struct audio_port *port) const;
const sp<AudioSourceDescriptor> mSource;
const sp<SourceClientDescriptor> mSource;
};

@ -1,59 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <system/audio.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <RoutingStrategy.h>
#include <AudioPatch.h>
namespace android {
class SwAudioOutputDescriptor;
class HwAudioOutputDescriptor;
class DeviceDescriptor;
class AudioSourceDescriptor: public RefBase
{
public:
AudioSourceDescriptor(const sp<DeviceDescriptor> device, const audio_attributes_t *attributes,
uid_t uid) :
mDevice(device), mAttributes(*attributes), mUid(uid) {}
virtual ~AudioSourceDescriptor() {}
audio_patch_handle_t getHandle() const { return mPatchDesc->mHandle; }
status_t dump(int fd);
const sp<DeviceDescriptor> mDevice;
const audio_attributes_t mAttributes;
uid_t mUid;
sp<AudioPatch> mPatchDesc;
wp<SwAudioOutputDescriptor> mSwOutput;
wp<HwAudioOutputDescriptor> mHwOutput;
};
class AudioSourceCollection :
public DefaultKeyedVector< audio_patch_handle_t, sp<AudioSourceDescriptor> >
{
public:
status_t dump(int fd) const;
};
} // namespace android

@ -23,11 +23,17 @@
#include <system/audio.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include "AudioPatch.h"
namespace android {
class DeviceDescriptor;
class HwAudioOutputDescriptor;
class SwAudioOutputDescriptor;
class ClientDescriptor: public RefBase
{
public:
@ -58,6 +64,10 @@ private:
const audio_config_base_t mConfig;
const audio_port_handle_t mPreferredDeviceId; // selected input device port ID
bool mActive;
protected:
// FIXME: use until other descriptor classes have a dump to String8 method
int mDumpFd;
};
class TrackClientDescriptor: public ClientDescriptor
@ -104,6 +114,38 @@ private:
const audio_input_flags_t mFlags;
};
class SourceClientDescriptor: public TrackClientDescriptor
{
public:
SourceClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_attributes_t attributes,
const sp<AudioPatch>& patchDesc, const sp<DeviceDescriptor>& srcDevice,
audio_stream_type_t stream);
~SourceClientDescriptor() override = default;
sp<AudioPatch> patchDesc() const { return mPatchDesc; }
sp<DeviceDescriptor> srcDevice() const { return mSrcDevice; };
wp<SwAudioOutputDescriptor> swOutput() const { return mSwOutput; }
void setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput);
wp<HwAudioOutputDescriptor> hwOutput() const { return mHwOutput; }
void setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput);
using ClientDescriptor::dump;
status_t dump(String8& dst, int spaces, int index) override;
private:
const sp<AudioPatch> mPatchDesc;
const sp<DeviceDescriptor> mSrcDevice;
wp<SwAudioOutputDescriptor> mSwOutput;
wp<HwAudioOutputDescriptor> mHwOutput;
};
class SourceClientCollection :
public DefaultKeyedVector< audio_port_handle_t, sp<SourceClientDescriptor> >
{
public:
status_t dump(int fd) const;
};
typedef std::vector< sp<TrackClientDescriptor> > TrackClientVector;
typedef std::map< audio_port_handle_t, sp<TrackClientDescriptor> > TrackClientMap;
typedef std::vector< sp<RecordClientDescriptor> > RecordClientVector;

@ -558,9 +558,9 @@ status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescript
}
// HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source,
HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
AudioPolicyClientInterface *clientInterface)
: AudioOutputDescriptor(source->mDevice, clientInterface),
: AudioOutputDescriptor(source->srcDevice(), clientInterface),
mSource(source)
{
}
@ -576,7 +576,7 @@ status_t HwAudioOutputDescriptor::dump(int fd)
snprintf(buffer, SIZE, "Source:\n");
result.append(buffer);
write(fd, result.string(), result.size());
mSource->dump(fd);
mSource->dump(fd, 0, 0);
return NO_ERROR;
}
@ -590,13 +590,13 @@ void HwAudioOutputDescriptor::toAudioPortConfig(
struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig);
mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
}
void HwAudioOutputDescriptor::toAudioPort(
struct audio_port *port) const
{
mSource->mDevice->toAudioPort(port);
mSource->srcDevice()->toAudioPort(port);
}

@ -1,64 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "APM::AudioSourceDescriptor"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <utils/String8.h>
#include <media/AudioPolicyHelper.h>
#include <HwModule.h>
#include <AudioGain.h>
#include <AudioSourceDescriptor.h>
#include <DeviceDescriptor.h>
#include <IOProfile.h>
#include <AudioOutputDescriptor.h>
namespace android {
status_t AudioSourceDescriptor::dump(int fd)
{
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
snprintf(buffer, SIZE, "mStream: %d\n", audio_attributes_to_stream_type(&mAttributes));
result.append(buffer);
snprintf(buffer, SIZE, "mDevice:\n");
result.append(buffer);
write(fd, result.string(), result.size());
mDevice->dump(fd, 2 , 0);
return NO_ERROR;
}
status_t AudioSourceCollection::dump(int fd) const
{
const size_t SIZE = 256;
char buffer[SIZE];
snprintf(buffer, SIZE, "\nAudio sources dump:\n");
write(fd, buffer, strlen(buffer));
for (size_t i = 0; i < size(); i++) {
snprintf(buffer, SIZE, "- Source %d dump:\n", keyAt(i));
write(fd, buffer, strlen(buffer));
valueAt(i)->dump(fd);
}
return NO_ERROR;
}
}; //namespace android

@ -19,7 +19,13 @@
#include <utils/Log.h>
#include <utils/String8.h>
#include "AudioGain.h"
#include "AudioOutputDescriptor.h"
#include "AudioPatch.h"
#include "ClientDescriptor.h"
#include "DeviceDescriptor.h"
#include "HwModule.h"
#include "IOProfile.h"
namespace android {
@ -27,6 +33,9 @@ status_t ClientDescriptor::dump(int fd, int spaces, int index)
{
String8 out;
// FIXME: use until other descriptor classes have a dump to String8 method
mDumpFd = fd;
status_t status = dump(out, spaces, index);
if (status == NO_ERROR) {
write(fd, out.string(), out.size());
@ -65,4 +74,50 @@ status_t RecordClientDescriptor::dump(String8& out, int spaces, int index)
return NO_ERROR;
}
SourceClientDescriptor::SourceClientDescriptor(audio_port_handle_t portId, uid_t uid,
audio_attributes_t attributes, const sp<AudioPatch>& patchDesc,
const sp<DeviceDescriptor>& srcDevice, audio_stream_type_t stream) :
TrackClientDescriptor::TrackClientDescriptor(portId, uid, AUDIO_SESSION_NONE, attributes,
AUDIO_CONFIG_BASE_INITIALIZER, AUDIO_PORT_HANDLE_NONE, stream, AUDIO_OUTPUT_FLAG_NONE),
mPatchDesc(patchDesc), mSrcDevice(srcDevice)
{
}
void SourceClientDescriptor::setSwOutput(const sp<SwAudioOutputDescriptor>& swOutput)
{
mSwOutput = swOutput;
}
void SourceClientDescriptor::setHwOutput(const sp<HwAudioOutputDescriptor>& hwOutput)
{
mHwOutput = hwOutput;
}
status_t SourceClientDescriptor::dump(String8& out, int spaces, int index)
{
TrackClientDescriptor::dump(out, spaces, index);
if (mDumpFd >= 0) {
out.appendFormat("%*s- Device:\n", spaces, "");
write(mDumpFd, out.string(), out.size());
mSrcDevice->dump(mDumpFd, 2, 0);
mDumpFd = -1;
}
return NO_ERROR;
}
status_t SourceClientCollection::dump(int fd) const
{
String8 out;
out.append("\nAudio sources:\n");
write(fd, out.string(), out.size());
for (size_t i = 0; i < size(); i++) {
valueAt(i)->dump(fd, 2, i);
}
return NO_ERROR;
}
}; //namespace android

@ -2794,6 +2794,7 @@ status_t AudioPolicyManager::dump(int fd)
mEffects.dump(fd);
mAudioPatches.dump(fd);
mPolicyMixes.dump(fd);
mAudioSources.dump(fd);
return NO_ERROR;
}
@ -3436,8 +3437,8 @@ void AudioPolicyManager::clearSessionRoutes(uid_t uid)
void AudioPolicyManager::clearAudioSources(uid_t uid)
{
for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--) {
sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc->mUid == uid) {
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc->uid() == uid) {
stopAudioSource(mAudioSources.keyAt(i));
}
}
@ -3455,20 +3456,23 @@ status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session
}
status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle,
uid_t uid)
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
uid_t uid)
{
ALOGV("%s source %p attributes %p handle %p", __FUNCTION__, source, attributes, handle);
if (source == NULL || attributes == NULL || handle == NULL) {
ALOGV("%s", __FUNCTION__);
*portId = AUDIO_PORT_HANDLE_NONE;
if (source == NULL || attributes == NULL || portId == NULL) {
ALOGW("%s invalid argument: source %p attributes %p handle %p",
__FUNCTION__, source, attributes, portId);
return BAD_VALUE;
}
*handle = AUDIO_PATCH_HANDLE_NONE;
if (source->role != AUDIO_PORT_ROLE_SOURCE ||
source->type != AUDIO_PORT_TYPE_DEVICE) {
ALOGV("%s INVALID_OPERATION source->role %d source->type %d", __FUNCTION__, source->role, source->type);
ALOGW("%s INVALID_OPERATION source->role %d source->type %d",
__FUNCTION__, source->role, source->type);
return INVALID_OPERATION;
}
@ -3476,34 +3480,37 @@ status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *so
mAvailableInputDevices.getDevice(source->ext.device.type,
String8(source->ext.device.address));
if (srcDeviceDesc == 0) {
ALOGV("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
ALOGW("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
return BAD_VALUE;
}
sp<AudioSourceDescriptor> sourceDesc =
new AudioSourceDescriptor(srcDeviceDesc, attributes, uid);
*portId = AudioPort::getNextUniqueId();
struct audio_patch dummyPatch = {};
sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
sourceDesc->mPatchDesc = patchDesc;
sp<SourceClientDescriptor> sourceDesc =
new SourceClientDescriptor(*portId, uid, *attributes, patchDesc, srcDeviceDesc,
streamTypefromAttributesInt(attributes));
status_t status = connectAudioSource(sourceDesc);
if (status == NO_ERROR) {
mAudioSources.add(sourceDesc->getHandle(), sourceDesc);
*handle = sourceDesc->getHandle();
mAudioSources.add(*portId, sourceDesc);
}
return status;
}
status_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
status_t AudioPolicyManager::connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
{
ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
ALOGV("%s handle %d", __FUNCTION__, sourceDesc->portId());
// make sure we only have one patch per source.
disconnectAudioSource(sourceDesc);
routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice;
audio_attributes_t attributes = sourceDesc->attributes();
routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
audio_stream_type_t stream = sourceDesc->stream();
sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->srcDevice();
audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true);
sp<DeviceDescriptor> sinkDeviceDesc =
@ -3548,7 +3555,7 @@ status_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>&
0);
ALOGV("%s patch panel returned %d patchHandle %d", __FUNCTION__,
status, afPatchHandle);
sourceDesc->mPatchDesc->mPatch = *patchBuilder.patch();
sourceDesc->patchDesc()->mPatch = *patchBuilder.patch();
if (status != NO_ERROR) {
ALOGW("%s patch panel could not connect device patch, error %d",
__FUNCTION__, status);
@ -3558,32 +3565,32 @@ status_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>&
status = startSource(outputDesc, stream, sinkDevice, NULL, &delayMs);
if (status != NO_ERROR) {
mpClientInterface->releaseAudioPatch(sourceDesc->mPatchDesc->mAfPatchHandle, 0);
mpClientInterface->releaseAudioPatch(sourceDesc->patchDesc()->mAfPatchHandle, 0);
return status;
}
sourceDesc->mSwOutput = outputDesc;
sourceDesc->setSwOutput(outputDesc);
if (delayMs != 0) {
usleep(delayMs * 1000);
}
}
sourceDesc->mPatchDesc->mAfPatchHandle = afPatchHandle;
addAudioPatch(sourceDesc->mPatchDesc->mHandle, sourceDesc->mPatchDesc);
sourceDesc->patchDesc()->mAfPatchHandle = afPatchHandle;
addAudioPatch(sourceDesc->patchDesc()->mHandle, sourceDesc->patchDesc());
return NO_ERROR;
}
status_t AudioPolicyManager::stopAudioSource(audio_patch_handle_t handle)
status_t AudioPolicyManager::stopAudioSource(audio_port_handle_t portId)
{
sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueFor(handle);
ALOGV("%s handle %d", __FUNCTION__, handle);
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueFor(portId);
ALOGV("%s port ID %d", __FUNCTION__, portId);
if (sourceDesc == 0) {
ALOGW("%s unknown source for handle %d", __FUNCTION__, handle);
ALOGW("%s unknown source for port ID %d", __FUNCTION__, portId);
return BAD_VALUE;
}
status_t status = disconnectAudioSource(sourceDesc);
mAudioSources.removeItem(handle);
mAudioSources.removeItem(portId);
return status;
}
@ -3917,20 +3924,20 @@ void AudioPolicyManager::setRecordSilenced(uid_t uid, bool silenced)
}
}
status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
status_t AudioPolicyManager::disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc)
{
ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
ALOGV("%s port Id %d", __FUNCTION__, sourceDesc->portId());
sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->mPatchDesc->mHandle);
sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->patchDesc()->mHandle);
if (patchDesc == 0) {
ALOGW("%s source has no patch with handle %d", __FUNCTION__,
sourceDesc->mPatchDesc->mHandle);
sourceDesc->patchDesc()->mHandle);
return BAD_VALUE;
}
removeAudioPatch(sourceDesc->mPatchDesc->mHandle);
removeAudioPatch(sourceDesc->patchDesc()->mHandle);
audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote();
audio_stream_type_t stream = sourceDesc->stream();
sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->swOutput().promote();
if (swOutputDesc != 0) {
status_t status = stopSource(swOutputDesc, stream, false);
if (status == NO_ERROR) {
@ -3938,7 +3945,7 @@ status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescripto
}
mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
} else {
sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->mHwOutput.promote();
sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->hwOutput().promote();
if (hwOutputDesc != 0) {
// release patch between src device and output device
// close Hwoutput and remove from mHwOutputs
@ -3949,15 +3956,16 @@ status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescripto
return NO_ERROR;
}
sp<AudioSourceDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
sp<SourceClientDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
audio_io_handle_t output, routing_strategy strategy)
{
sp<AudioSourceDescriptor> source;
sp<SourceClientDescriptor> source;
for (size_t i = 0; i < mAudioSources.size(); i++) {
sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
audio_attributes_t attributes = sourceDesc->attributes();
routing_strategy sourceStrategy =
(routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->mSwOutput.promote();
(routing_strategy) getStrategyForAttr(&attributes);
sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->swOutput().promote();
if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
source = sourceDesc;
break;
@ -4841,7 +4849,7 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
setStrategyMute(strategy, true, desc);
setStrategyMute(strategy, false, desc, maxLatency * LATENCY_MUTE_FACTOR, newDevice);
}
sp<AudioSourceDescriptor> source =
sp<SourceClientDescriptor> source =
getSourceForStrategyOnOutput(srcOut, strategy);
if (source != 0){
connectAudioSource(source);
@ -5922,10 +5930,10 @@ bool AudioPolicyManager::isStateInCall(int state)
void AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc)
{
for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--) {
sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc->mDevice->equals(deviceDesc)) {
ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->getHandle());
stopAudioSource(sourceDesc->getHandle());
sp<SourceClientDescriptor> sourceDesc = mAudioSources.valueAt(i);
if (sourceDesc->srcDevice()->equals(deviceDesc)) {
ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->portId());
stopAudioSource(sourceDesc->portId());
}
}

@ -223,9 +223,9 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle,
audio_port_handle_t *portId,
uid_t uid);
virtual status_t stopAudioSource(audio_patch_handle_t handle);
virtual status_t stopAudioSource(audio_port_handle_t portId);
virtual status_t setMasterMono(bool mono);
virtual status_t getMasterMono(bool *mono);
@ -525,10 +525,10 @@ protected:
status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
status_t connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc);
status_t disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc);
status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
status_t disconnectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
sp<AudioSourceDescriptor> getSourceForStrategyOnOutput(audio_io_handle_t output,
sp<SourceClientDescriptor> getSourceForStrategyOnOutput(audio_io_handle_t output,
routing_strategy strategy);
void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc);
@ -587,7 +587,7 @@ protected:
sp<AudioPatch> mCallRxPatch;
HwAudioOutputCollection mHwOutputs;
AudioSourceCollection mAudioSources;
SourceClientCollection mAudioSources;
// for supporting "beacon" streams, i.e. streams that only play on speaker, and never
// when something other than STREAM_TTS (a.k.a. "Transmitted Through Speaker") is playing

@ -990,26 +990,26 @@ status_t AudioPolicyService::registerPolicyMixes(const Vector<AudioMix>& mixes,
}
status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle)
const audio_attributes_t *attributes,
audio_port_handle_t *portId)
{
Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
AutoCallerClear acc;
return mAudioPolicyManager->startAudioSource(source, attributes, handle,
return mAudioPolicyManager->startAudioSource(source, attributes, portId,
IPCThreadState::self()->getCallingUid());
}
status_t AudioPolicyService::stopAudioSource(audio_patch_handle_t handle)
status_t AudioPolicyService::stopAudioSource(audio_port_handle_t portId)
{
Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
AutoCallerClear acc;
return mAudioPolicyManager->stopAudioSource(handle);
return mAudioPolicyManager->stopAudioSource(portId);
}
status_t AudioPolicyService::setMasterMono(bool mono)

@ -184,8 +184,8 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_patch_handle_t *handle);
virtual status_t stopAudioSource(audio_patch_handle_t handle);
audio_port_handle_t *portId);
virtual status_t stopAudioSource(audio_port_handle_t portId);
virtual status_t setMasterMono(bool mono);
virtual status_t getMasterMono(bool *mono);

Loading…
Cancel
Save