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, status_t AudioSystem::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes, const audio_attributes_t *attributes,
audio_patch_handle_t *handle) audio_port_handle_t *portId)
{ {
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED; 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(); const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED; if (aps == 0) return PERMISSION_DENIED;
return aps->stopAudioSource(handle); return aps->stopAudioSource(portId);
} }
status_t AudioSystem::setMasterMono(bool mono) status_t AudioSystem::setMasterMono(bool mono)

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

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

@ -153,8 +153,8 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source, virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes, const audio_attributes_t *attributes,
audio_patch_handle_t *handle) = 0; audio_port_handle_t *portId) = 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 setMasterMono(bool mono) = 0;
virtual status_t getMasterMono(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, virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes, const audio_attributes_t *attributes,
audio_patch_handle_t *handle, audio_port_handle_t *portId,
uid_t uid) = 0; 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 setMasterMono(bool mono) = 0;
virtual status_t getMasterMono(bool *mono) = 0; virtual status_t getMasterMono(bool *mono) = 0;

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

@ -24,7 +24,6 @@
#include <RoutingStrategy.h> #include <RoutingStrategy.h>
#include "AudioIODescriptorInterface.h" #include "AudioIODescriptorInterface.h"
#include "AudioPort.h" #include "AudioPort.h"
#include "AudioSourceDescriptor.h"
#include "ClientDescriptor.h" #include "ClientDescriptor.h"
namespace android { namespace android {
@ -159,7 +158,7 @@ public:
class HwAudioOutputDescriptor: public AudioOutputDescriptor class HwAudioOutputDescriptor: public AudioOutputDescriptor
{ {
public: public:
HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source, HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
AudioPolicyClientInterface *clientInterface); AudioPolicyClientInterface *clientInterface);
virtual ~HwAudioOutputDescriptor() {} virtual ~HwAudioOutputDescriptor() {}
@ -176,7 +175,7 @@ public:
const struct audio_port_config *srcConfig = NULL) const; const struct audio_port_config *srcConfig = NULL) const;
virtual void toAudioPort(struct audio_port *port) 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 <system/audio.h>
#include <utils/Errors.h> #include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h> #include <utils/RefBase.h>
#include <utils/String8.h> #include <utils/String8.h>
#include "AudioPatch.h"
namespace android { namespace android {
class DeviceDescriptor;
class HwAudioOutputDescriptor;
class SwAudioOutputDescriptor;
class ClientDescriptor: public RefBase class ClientDescriptor: public RefBase
{ {
public: public:
@ -58,6 +64,10 @@ private:
const audio_config_base_t mConfig; const audio_config_base_t mConfig;
const audio_port_handle_t mPreferredDeviceId; // selected input device port ID const audio_port_handle_t mPreferredDeviceId; // selected input device port ID
bool mActive; bool mActive;
protected:
// FIXME: use until other descriptor classes have a dump to String8 method
int mDumpFd;
}; };
class TrackClientDescriptor: public ClientDescriptor class TrackClientDescriptor: public ClientDescriptor
@ -104,6 +114,38 @@ private:
const audio_input_flags_t mFlags; 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::vector< sp<TrackClientDescriptor> > TrackClientVector;
typedef std::map< audio_port_handle_t, sp<TrackClientDescriptor> > TrackClientMap; typedef std::map< audio_port_handle_t, sp<TrackClientDescriptor> > TrackClientMap;
typedef std::vector< sp<RecordClientDescriptor> > RecordClientVector; typedef std::vector< sp<RecordClientDescriptor> > RecordClientVector;

@ -558,9 +558,9 @@ status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescript
} }
// HwAudioOutputDescriptor implementation // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source, HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
AudioPolicyClientInterface *clientInterface) AudioPolicyClientInterface *clientInterface)
: AudioOutputDescriptor(source->mDevice, clientInterface), : AudioOutputDescriptor(source->srcDevice(), clientInterface),
mSource(source) mSource(source)
{ {
} }
@ -576,7 +576,7 @@ status_t HwAudioOutputDescriptor::dump(int fd)
snprintf(buffer, SIZE, "Source:\n"); snprintf(buffer, SIZE, "Source:\n");
result.append(buffer); result.append(buffer);
write(fd, result.string(), result.size()); write(fd, result.string(), result.size());
mSource->dump(fd); mSource->dump(fd, 0, 0);
return NO_ERROR; return NO_ERROR;
} }
@ -590,13 +590,13 @@ void HwAudioOutputDescriptor::toAudioPortConfig(
struct audio_port_config *dstConfig, struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const const struct audio_port_config *srcConfig) const
{ {
mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig); mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
} }
void HwAudioOutputDescriptor::toAudioPort( void HwAudioOutputDescriptor::toAudioPort(
struct audio_port *port) const 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/Log.h>
#include <utils/String8.h> #include <utils/String8.h>
#include "AudioGain.h"
#include "AudioOutputDescriptor.h"
#include "AudioPatch.h"
#include "ClientDescriptor.h" #include "ClientDescriptor.h"
#include "DeviceDescriptor.h"
#include "HwModule.h"
#include "IOProfile.h"
namespace android { namespace android {
@ -27,6 +33,9 @@ status_t ClientDescriptor::dump(int fd, int spaces, int index)
{ {
String8 out; String8 out;
// FIXME: use until other descriptor classes have a dump to String8 method
mDumpFd = fd;
status_t status = dump(out, spaces, index); status_t status = dump(out, spaces, index);
if (status == NO_ERROR) { if (status == NO_ERROR) {
write(fd, out.string(), out.size()); write(fd, out.string(), out.size());
@ -65,4 +74,50 @@ status_t RecordClientDescriptor::dump(String8& out, int spaces, int index)
return NO_ERROR; 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 }; //namespace android

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

@ -223,9 +223,9 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source, virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes, const audio_attributes_t *attributes,
audio_patch_handle_t *handle, audio_port_handle_t *portId,
uid_t uid); 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 setMasterMono(bool mono);
virtual status_t getMasterMono(bool *mono); virtual status_t getMasterMono(bool *mono);
@ -525,10 +525,10 @@ protected:
status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; } status_t hasPrimaryOutput() const { return mPrimaryOutput != 0; }
status_t connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc); status_t connectAudioSource(const sp<SourceClientDescriptor>& sourceDesc);
status_t disconnectAudioSource(const sp<AudioSourceDescriptor>& 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); routing_strategy strategy);
void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc); void cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc);
@ -587,7 +587,7 @@ protected:
sp<AudioPatch> mCallRxPatch; sp<AudioPatch> mCallRxPatch;
HwAudioOutputCollection mHwOutputs; HwAudioOutputCollection mHwOutputs;
AudioSourceCollection mAudioSources; SourceClientCollection mAudioSources;
// for supporting "beacon" streams, i.e. streams that only play on speaker, and never // 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 // 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, status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes, const audio_attributes_t *attributes,
audio_patch_handle_t *handle) audio_port_handle_t *portId)
{ {
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) { if (mAudioPolicyManager == NULL) {
return NO_INIT; return NO_INIT;
} }
AutoCallerClear acc; AutoCallerClear acc;
return mAudioPolicyManager->startAudioSource(source, attributes, handle, return mAudioPolicyManager->startAudioSource(source, attributes, portId,
IPCThreadState::self()->getCallingUid()); 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); Mutex::Autolock _l(mLock);
if (mAudioPolicyManager == NULL) { if (mAudioPolicyManager == NULL) {
return NO_INIT; return NO_INIT;
} }
AutoCallerClear acc; AutoCallerClear acc;
return mAudioPolicyManager->stopAudioSource(handle); return mAudioPolicyManager->stopAudioSource(portId);
} }
status_t AudioPolicyService::setMasterMono(bool mono) status_t AudioPolicyService::setMasterMono(bool mono)

@ -184,8 +184,8 @@ public:
virtual status_t startAudioSource(const struct audio_port_config *source, virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes, const audio_attributes_t *attributes,
audio_patch_handle_t *handle); audio_port_handle_t *portId);
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 setMasterMono(bool mono);
virtual status_t getMasterMono(bool *mono); virtual status_t getMasterMono(bool *mono);

Loading…
Cancel
Save