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
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index c072901..cb4bcfc 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -878,31 +878,25 @@
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,
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 316105c..9d77376 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -244,41 +244,29 @@
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 @@
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;
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 4c0f796..10d6e92 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -224,15 +224,9 @@
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().
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index c3876af..6c017a3 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -66,15 +66,9 @@
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,
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 53a4ce9..0687a7c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -306,7 +306,7 @@
*sessionId = actualSessionId;
} else {
if (direction == MmapStreamInterface::DIRECTION_OUTPUT) {
- AudioSystem::releaseOutput(io, streamType, actualSessionId);
+ AudioSystem::releaseOutput(portId);
} else {
AudioSystem::releaseInput(portId);
}
@@ -777,7 +777,7 @@
Exit:
if (lStatus != NO_ERROR && output.outputId != AUDIO_IO_HANDLE_NONE) {
- AudioSystem::releaseOutput(output.outputId, streamType, sessionId);
+ AudioSystem::releaseOutput(portId);
}
*status = lStatus;
return trackHandle;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f68bfee..ca5ae14 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2324,15 +2324,13 @@
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 @@
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 @@
}
// 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 @@
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 @@
if (mActiveTracks.size() != 0) {
mLock.unlock();
if (isOutput()) {
- AudioSystem::releaseOutput(mId, streamType(), mSessionId);
+ AudioSystem::releaseOutput(portId);
} else {
AudioSystem::releaseInput(portId);
}
@@ -8298,8 +8294,8 @@
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());
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 22e610e..8b9485f 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -486,7 +486,7 @@
wasActive = playbackThread->destroyTrack_l(this);
}
if (isExternalTrack() && !wasActive) {
- AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, mSessionId);
+ AudioSystem::releaseOutput(mPortId);
}
}
}
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index d2bc40d..859072b 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -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 @@
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 @@
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 @@
{
AutoCallerClear acc;
status = mAudioPolicyManager->startInput(
- client->input, client->session, *silenced, &concurrency);
+ client->io, client->session, *silenced, &concurrency);
}
@@ -610,7 +641,7 @@
// 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 @@
}
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);
}
}
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index ca3b6b6..8bca221 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -695,26 +695,26 @@
}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 @@
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);
}
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index a1366bb..d41069e 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -81,15 +81,9 @@
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 @@
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 @@
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 @@
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 @@
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 @@
sp<UidPolicy> mUidPolicy;
DefaultKeyedVector< audio_port_handle_t, sp<AudioRecordClient> > mAudioRecordClients;
+ DefaultKeyedVector< audio_port_handle_t, sp<AudioPlaybackClient> > mAudioPlaybackClients;
};
} // namespace android