audio policy: refactor audio playback APIs

Refactor audio policy service APIs controlling audio playback (startOutput, stopOutput, releaseOutput)
To allow finer grain control per AudioTrack client.

Test: AudioTrack CTS test. manual test of playback use cases.
Change-Id: I49a681f3c2a8211e524824993049b24d8086376d
gugelfrei
Eric Laurent 6 years ago
parent b05e9b139f
commit d7fe086d3b

@ -878,31 +878,25 @@ status_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
flags, selectedDeviceId, portId);
}
status_t AudioSystem::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
status_t AudioSystem::startOutput(audio_port_handle_t portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->startOutput(output, stream, session);
return aps->startOutput(portId);
}
status_t AudioSystem::stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
status_t AudioSystem::stopOutput(audio_port_handle_t portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->stopOutput(output, stream, session);
return aps->stopOutput(portId);
}
void AudioSystem::releaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
void AudioSystem::releaseOutput(audio_port_handle_t portId)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return;
aps->releaseOutput(output, stream, session);
aps->releaseOutput(portId);
}
status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,

@ -244,41 +244,29 @@ public:
return status;
}
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
virtual status_t startOutput(audio_port_handle_t portId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(output);
data.writeInt32((int32_t) stream);
data.writeInt32((int32_t) session);
data.writeInt32((int32_t)portId);
remote()->transact(START_OUTPUT, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
virtual status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
virtual status_t stopOutput(audio_port_handle_t portId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(output);
data.writeInt32((int32_t) stream);
data.writeInt32((int32_t) session);
data.writeInt32((int32_t)portId);
remote()->transact(STOP_OUTPUT, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
virtual void releaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
virtual void releaseOutput(audio_port_handle_t portId)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(output);
data.writeInt32((int32_t)stream);
data.writeInt32((int32_t)session);
data.writeInt32((int32_t)portId);
remote()->transact(RELEASE_OUTPUT, data, &reply);
}
@ -1074,34 +1062,22 @@ status_t BnAudioPolicyService::onTransact(
case START_OUTPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
audio_stream_type_t stream =
static_cast <audio_stream_type_t>(data.readInt32());
audio_session_t session = (audio_session_t)data.readInt32();
reply->writeInt32(static_cast <uint32_t>(startOutput(output,
stream,
session)));
const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
reply->writeInt32(static_cast <uint32_t>(startOutput(portId)));
return NO_ERROR;
} break;
case STOP_OUTPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
audio_stream_type_t stream =
static_cast <audio_stream_type_t>(data.readInt32());
audio_session_t session = (audio_session_t)data.readInt32();
reply->writeInt32(static_cast <uint32_t>(stopOutput(output,
stream,
session)));
const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
reply->writeInt32(static_cast <uint32_t>(stopOutput(portId)));
return NO_ERROR;
} break;
case RELEASE_OUTPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
audio_stream_type_t stream = (audio_stream_type_t)data.readInt32();
audio_session_t session = (audio_session_t)data.readInt32();
releaseOutput(output, stream, session);
const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
releaseOutput(portId);
return NO_ERROR;
} break;

@ -224,15 +224,9 @@ public:
audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId);
static status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
static status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
static void releaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
static status_t startOutput(audio_port_handle_t portId);
static status_t stopOutput(audio_port_handle_t portId);
static void releaseOutput(audio_port_handle_t portId);
// Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
// or release it with releaseInput().

@ -66,15 +66,9 @@ public:
audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId) = 0;
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session) = 0;
virtual status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session) = 0;
virtual void releaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session) = 0;
virtual status_t startOutput(audio_port_handle_t portId) = 0;
virtual status_t stopOutput(audio_port_handle_t portId) = 0;
virtual void releaseOutput(audio_port_handle_t portId) = 0;
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,

@ -306,7 +306,7 @@ status_t AudioFlinger::openMmapStream(MmapStreamInterface::stream_direction_t di
*sessionId = actualSessionId;
} else {
if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
AudioSystem::releaseOutput(io, streamType, actualSessionId);
AudioSystem::releaseOutput(portId);
} else {
AudioSystem::releaseInput(portId);
}
@ -777,7 +777,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(const CreateTrackInput& input,
Exit:
if (lStatus != NO_ERROR && output.outputId != AUDIO_IO_HANDLE_NONE) {
AudioSystem::releaseOutput(output.outputId, streamType, sessionId);
AudioSystem::releaseOutput(portId);
}
*status = lStatus;
return trackHandle;

@ -2324,15 +2324,13 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
if (track->isExternalTrack()) {
TrackBase::track_state state = track->mState;
mLock.unlock();
status = AudioSystem::startOutput(mId, track->streamType(),
track->sessionId());
status = AudioSystem::startOutput(track->portId());
mLock.lock();
// abort track was stopped/paused while we released the lock
if (state != track->mState) {
if (status == NO_ERROR) {
mLock.unlock();
AudioSystem::stopOutput(mId, track->streamType(),
track->sessionId());
AudioSystem::stopOutput(track->portId());
mLock.lock();
}
return INVALID_OPERATION;
@ -2812,15 +2810,13 @@ void AudioFlinger::PlaybackThread::threadLoop_removeTracks(
for (size_t i = 0 ; i < count ; i++) {
const sp<Track>& track = tracksToRemove.itemAt(i);
if (track->isExternalTrack()) {
AudioSystem::stopOutput(mId, track->streamType(),
track->sessionId());
AudioSystem::stopOutput(track->portId());
#ifdef ADD_BATTERY_DATA
// to track the speaker usage
addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
#endif
if (track->isTerminated()) {
AudioSystem::releaseOutput(mId, track->streamType(),
track->sessionId());
AudioSystem::releaseOutput(track->portId());
}
}
}
@ -8100,7 +8096,7 @@ void AudioFlinger::MmapThread::disconnect()
}
// This will decrement references and may cause the destruction of this thread.
if (isOutput()) {
AudioSystem::releaseOutput(mId, streamType(), mSessionId);
AudioSystem::releaseOutput(mPortId);
} else {
AudioSystem::releaseInput(mPortId);
}
@ -8214,7 +8210,7 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
bool silenced = false;
if (isOutput()) {
ret = AudioSystem::startOutput(mId, streamType(), mSessionId);
ret = AudioSystem::startOutput(portId);
} else {
ret = AudioSystem::startInput(portId, &silenced);
}
@ -8226,7 +8222,7 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client,
if (mActiveTracks.size() != 0) {
mLock.unlock();
if (isOutput()) {
AudioSystem::releaseOutput(mId, streamType(), mSessionId);
AudioSystem::releaseOutput(portId);
} else {
AudioSystem::releaseInput(portId);
}
@ -8298,8 +8294,8 @@ status_t AudioFlinger::MmapThread::stop(audio_port_handle_t handle)
mLock.unlock();
if (isOutput()) {
AudioSystem::stopOutput(mId, streamType(), track->sessionId());
AudioSystem::releaseOutput(mId, streamType(), track->sessionId());
AudioSystem::stopOutput(track->portId());
AudioSystem::releaseOutput(track->portId());
} else {
AudioSystem::stopInput(track->portId());
AudioSystem::releaseInput(track->portId());

@ -486,7 +486,7 @@ void AudioFlinger::PlaybackThread::Track::destroy()
wasActive = playbackThread->destroyTrack_l(this);
}
if (isExternalTrack() && !wasActive) {
AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, mSessionId);
AudioSystem::releaseOutput(mPortId);
}
}
}

@ -17,12 +17,12 @@
#define LOG_TAG "AudioPolicyIntefaceImpl"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <media/MediaAnalyticsItem.h>
#include "AudioPolicyService.h"
#include <mediautils/ServiceUtilities.h>
#include "TypeConverter.h"
#include <media/AudioPolicyHelper.h>
#include <media/MediaAnalyticsItem.h>
#include <mediautils/ServiceUtilities.h>
#include <utils/Log.h>
namespace android {
@ -208,93 +208,128 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
config,
&flags, selectedDeviceId, portId);
}
if (result == NO_ERROR) {
sp <AudioPlaybackClient> client =
new AudioPlaybackClient(*attr, *output, uid, pid, session, *selectedDeviceId, *stream);
mAudioPlaybackClients.add(*portId, client);
}
return result;
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
status_t AudioPolicyService::startOutput(audio_port_handle_t portId)
{
if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
}
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
ALOGV("startOutput()");
sp<AudioPlaybackClient> client;
sp<AudioPolicyEffects>audioPolicyEffects;
{
Mutex::Autolock _l(mLock);
const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
if (index < 0) {
ALOGE("%s AudioTrack client not found for portId %d", __FUNCTION__, portId);
return INVALID_OPERATION;
}
client = mAudioPlaybackClients.valueAt(index);
audioPolicyEffects = mAudioPolicyEffects;
}
if (audioPolicyEffects != 0) {
// create audio processors according to stream
status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session);
status_t status = audioPolicyEffects->addOutputSessionEffects(
client->io, client->stream, client->session);
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGW("Failed to add effects on session %d", session);
ALOGW("Failed to add effects on session %d", client->session);
}
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->startOutput(output, stream, session);
status_t status = mAudioPolicyManager->startOutput(
client->io, client->stream, client->session);
if (status == NO_ERROR) {
client->active = true;
}
return status;
}
status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
status_t AudioPolicyService::stopOutput(audio_port_handle_t portId)
{
if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
{
Mutex::Autolock _l(mLock);
const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
if (index < 0) {
ALOGE("%s AudioTrack client not found for portId %d", __FUNCTION__, portId);
return INVALID_OPERATION;
}
}
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
ALOGV("stopOutput()");
mOutputCommandThread->stopOutputCommand(output, stream, session);
mOutputCommandThread->stopOutputCommand(portId);
return NO_ERROR;
}
status_t AudioPolicyService::doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
status_t AudioPolicyService::doStopOutput(audio_port_handle_t portId)
{
ALOGV("doStopOutput from tid %d", gettid());
ALOGV("doStopOutput");
sp<AudioPlaybackClient> client;
sp<AudioPolicyEffects>audioPolicyEffects;
{
Mutex::Autolock _l(mLock);
const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
if (index < 0) {
ALOGE("%s AudioTrack client not found for portId %d", __FUNCTION__, portId);
return INVALID_OPERATION;
}
client = mAudioPlaybackClients.valueAt(index);
audioPolicyEffects = mAudioPolicyEffects;
}
if (audioPolicyEffects != 0) {
// release audio processors from the stream
status_t status = audioPolicyEffects->releaseOutputSessionEffects(output, stream, session);
status_t status = audioPolicyEffects->releaseOutputSessionEffects(
client->io, client->stream, client->session);
if (status != NO_ERROR && status != ALREADY_EXISTS) {
ALOGW("Failed to release effects on session %d", session);
ALOGW("Failed to release effects on session %d", client->session);
}
}
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->stopOutput(output, stream, session);
status_t status = mAudioPolicyManager->stopOutput(
client->io, client->stream, client->session);
if (status == NO_ERROR) {
client->active = false;
}
return status;
}
void AudioPolicyService::releaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
void AudioPolicyService::releaseOutput(audio_port_handle_t portId)
{
if (mAudioPolicyManager == NULL) {
return;
}
ALOGV("releaseOutput()");
mOutputCommandThread->releaseOutputCommand(output, stream, session);
mOutputCommandThread->releaseOutputCommand(portId);
}
void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
void AudioPolicyService::doReleaseOutput(audio_port_handle_t portId)
{
ALOGV("doReleaseOutput from tid %d", gettid());
Mutex::Autolock _l(mLock);
const ssize_t index = mAudioPlaybackClients.indexOfKey(portId);
if (index < 0) {
ALOGE("%s AudioTrack client not found for portId %d", __FUNCTION__, portId);
return;
}
sp<AudioPlaybackClient> client = mAudioPlaybackClients.valueAt(index);
mAudioRecordClients.removeItem(portId);
// called from internal thread: no need to clear caller identity
mAudioPolicyManager->releaseOutput(output, stream, session);
mAudioPolicyManager->releaseOutput(
client->io, client->stream, client->session);
}
status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
@ -403,12 +438,8 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
return status;
}
sp<AudioRecordClient> client =
new AudioRecordClient(*attr, *input, uid, pid, opPackageName, session);
client->active = false;
client->isConcurrent = false;
client->isVirtualDevice = false; //TODO : update from APM->getInputForAttr()
client->deviceId = *selectedDeviceId;
sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session,
*selectedDeviceId, opPackageName);
mAudioRecordClients.add(*portId, client);
}
@ -497,7 +528,7 @@ status_t AudioPolicyService::startInput(audio_port_handle_t portId, bool *silenc
{
AutoCallerClear acc;
status = mAudioPolicyManager->startInput(
client->input, client->session, *silenced, &concurrency);
client->io, client->session, *silenced, &concurrency);
}
@ -610,7 +641,7 @@ status_t AudioPolicyService::stopInput(audio_port_handle_t portId)
// finish the recording app op
finishRecording(client->opPackageName, client->uid);
AutoCallerClear acc;
return mAudioPolicyManager->stopInput(client->input, client->session);
return mAudioPolicyManager->stopInput(client->io, client->session);
}
void AudioPolicyService::releaseInput(audio_port_handle_t portId)
@ -635,15 +666,15 @@ void AudioPolicyService::releaseInput(audio_port_handle_t portId)
}
if (audioPolicyEffects != 0) {
// release audio processors from the input
status_t status = audioPolicyEffects->releaseInputEffects(client->input, client->session);
status_t status = audioPolicyEffects->releaseInputEffects(client->io, client->session);
if(status != NO_ERROR) {
ALOGW("Failed to release effects on input %d", client->input);
ALOGW("Failed to release effects on input %d", client->io);
}
}
{
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
mAudioPolicyManager->releaseInput(client->input, client->session);
mAudioPolicyManager->releaseInput(client->io, client->session);
}
}

@ -695,26 +695,26 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
}break;
case STOP_OUTPUT: {
StopOutputData *data = (StopOutputData *)command->mParam.get();
ALOGV("AudioCommandThread() processing stop output %d",
data->mIO);
ALOGV("AudioCommandThread() processing stop output portId %d",
data->mPortId);
svc = mService.promote();
if (svc == 0) {
break;
}
mLock.unlock();
svc->doStopOutput(data->mIO, data->mStream, data->mSession);
svc->doStopOutput(data->mPortId);
mLock.lock();
}break;
case RELEASE_OUTPUT: {
ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
ALOGV("AudioCommandThread() processing release output %d",
data->mIO);
ALOGV("AudioCommandThread() processing release output portId %d",
data->mPortId);
svc = mService.promote();
if (svc == 0) {
break;
}
mLock.unlock();
svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
svc->doReleaseOutput(data->mPortId);
mLock.lock();
}break;
case CREATE_AUDIO_PATCH: {
@ -925,33 +925,25 @@ status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume
return sendCommand(command, delayMs);
}
void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_port_handle_t portId)
{
sp<AudioCommand> command = new AudioCommand();
command->mCommand = STOP_OUTPUT;
sp<StopOutputData> data = new StopOutputData();
data->mIO = output;
data->mStream = stream;
data->mSession = session;
data->mPortId = portId;
command->mParam = data;
ALOGV("AudioCommandThread() adding stop output %d", output);
ALOGV("AudioCommandThread() adding stop output portId %d", portId);
sendCommand(command);
}
void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session)
void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_port_handle_t portId)
{
sp<AudioCommand> command = new AudioCommand();
command->mCommand = RELEASE_OUTPUT;
sp<ReleaseOutputData> data = new ReleaseOutputData();
data->mIO = output;
data->mStream = stream;
data->mSession = session;
data->mPortId = portId;
command->mParam = data;
ALOGV("AudioCommandThread() adding release output %d", output);
ALOGV("AudioCommandThread() adding release output portId %d", portId);
sendCommand(command);
}

@ -81,15 +81,9 @@ public:
audio_output_flags_t flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
virtual status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
virtual void releaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
virtual status_t startOutput(audio_port_handle_t portId);
virtual status_t stopOutput(audio_port_handle_t portId);
virtual void releaseOutput(audio_port_handle_t portId);
virtual status_t getInputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *input,
audio_session_t session,
@ -205,12 +199,8 @@ public:
bool reported);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
status_t doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
void doReleaseOutput(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
status_t doStopOutput(audio_port_handle_t portId);
void doReleaseOutput(audio_port_handle_t portId);
status_t clientCreateAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle,
@ -340,12 +330,8 @@ private:
status_t parametersCommand(audio_io_handle_t ioHandle,
const char *keyValuePairs, int delayMs = 0);
status_t voiceVolumeCommand(float volume, int delayMs = 0);
void stopOutputCommand(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
void releaseOutputCommand(audio_io_handle_t output,
audio_stream_type_t stream,
audio_session_t session);
void stopOutputCommand(audio_port_handle_t portId);
void releaseOutputCommand(audio_port_handle_t portId);
status_t sendCommand(sp<AudioCommand>& command, int delayMs = 0);
void insertCommand_l(sp<AudioCommand>& command, int delayMs = 0);
status_t createAudioPatchCommand(const struct audio_patch *patch,
@ -413,16 +399,12 @@ private:
class StopOutputData : public AudioCommandData {
public:
audio_io_handle_t mIO;
audio_stream_type_t mStream;
audio_session_t mSession;
audio_port_handle_t mPortId;
};
class ReleaseOutputData : public AudioCommandData {
public:
audio_io_handle_t mIO;
audio_stream_type_t mStream;
audio_session_t mSession;
audio_port_handle_t mPortId;
};
class CreateAudioPatchData : public AudioCommandData {
@ -603,30 +585,56 @@ private:
bool mAudioPortCallbacksEnabled;
};
class AudioClient : public virtual RefBase {
public:
AudioClient(const audio_attributes_t attributes,
const audio_io_handle_t io, uid_t uid, pid_t pid,
const audio_session_t session, const audio_port_handle_t deviceId) :
attributes(attributes), io(io), uid(uid), pid(pid),
session(session), deviceId(deviceId), active(false) {}
~AudioClient() override = default;
const audio_attributes_t attributes; // source, flags ...
const audio_io_handle_t io; // audio HAL stream IO handle
const uid_t uid; // client UID
const pid_t pid; // client PID
const audio_session_t session; // audio session ID
const audio_port_handle_t deviceId; // selected input device port ID
bool active; // Playback/Capture is active or inactive
};
// --- AudioRecordClient ---
// Information about each registered AudioRecord client
// (between calls to getInputForAttr() and releaseInput())
class AudioRecordClient : public RefBase {
class AudioRecordClient : public AudioClient {
public:
AudioRecordClient(const audio_attributes_t attributes,
const audio_io_handle_t input, uid_t uid, pid_t pid,
const String16& opPackageName, const audio_session_t session) :
attributes(attributes),
input(input), uid(uid), pid(pid),
opPackageName(opPackageName), session(session),
active(false), isConcurrent(false), isVirtualDevice(false) {}
virtual ~AudioRecordClient() {}
const audio_io_handle_t io, uid_t uid, pid_t pid,
const audio_session_t session, const audio_port_handle_t deviceId,
const String16& opPackageName) :
AudioClient(attributes, io, uid, pid, session, deviceId),
opPackageName(opPackageName), isConcurrent(false), isVirtualDevice(false) {}
~AudioRecordClient() override = default;
const audio_attributes_t attributes; // source, flags ...
const audio_io_handle_t input; // audio HAL input IO handle
const uid_t uid; // client UID
const pid_t pid; // client PID
const String16 opPackageName; // client package name
const audio_session_t session; // audio session ID
bool active; // Capture is active or inactive
bool isConcurrent; // is allowed to concurrent capture
bool isVirtualDevice; // uses virtual device: updated by APM::getInputForAttr()
audio_port_handle_t deviceId; // selected input device port ID
};
// --- AudioPlaybackClient ---
// Information about each registered AudioTrack client
// (between calls to getOutputForAttr() and releaseOutput())
class AudioPlaybackClient : public AudioClient {
public:
AudioPlaybackClient(const audio_attributes_t attributes,
const audio_io_handle_t io, uid_t uid, pid_t pid,
const audio_session_t session, audio_port_handle_t deviceId,
audio_stream_type_t stream) :
AudioClient(attributes, io, uid, pid, session, deviceId), stream(stream) {}
~AudioPlaybackClient() override = default;
const audio_stream_type_t stream;
};
// A class automatically clearing and restoring binder caller identity inside
@ -670,6 +678,7 @@ private:
sp<UidPolicy> mUidPolicy;
DefaultKeyedVector< audio_port_handle_t, sp<AudioRecordClient> > mAudioRecordClients;
DefaultKeyedVector< audio_port_handle_t, sp<AudioPlaybackClient> > mAudioPlaybackClients;
};
} // namespace android

Loading…
Cancel
Save