summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-11-14 10:06:21 -0800
committerEric Laurent <elaurent@google.com>2014-11-25 12:48:19 -0800
commite83b55dc29ca16092ba02f36f55fa6e0e37fd78c (patch)
treef8232611b6372b74579e3ed03dfbeb167011d257
parent0f78eabb733e1413d7febd00c0bad0f0add02314 (diff)
downloadframeworks_av-e83b55dc29ca16092ba02f36f55fa6e0e37fd78c.zip
frameworks_av-e83b55dc29ca16092ba02f36f55fa6e0e37fd78c.tar.gz
frameworks_av-e83b55dc29ca16092ba02f36f55fa6e0e37fd78c.tar.bz2
audio policy: new getOutputForAttr() prototype.
Update getOutputForAttr() prototype and group all logic dealing with audio attributes to stream type conversion in audio policy manager. getOutputForAttr(): - specifies the audio session (for future use) - returns a status code - receives either stream type (for legacy) or audio attributes - returns an updated streamtype Remove logic dealing with legacy stream types to attributes conversion from AudioTrack. Use correct type for audio sessions in other APIs (startOutput() ...). releaseOutput() specifies the audio session (for future use). Bug: 18067208. Change-Id: I1bfbe9626c04c7955d77f8a70aecfad2cb204817
-rw-r--r--include/media/AudioPolicyHelper.h53
-rw-r--r--include/media/AudioSystem.h15
-rw-r--r--include/media/AudioTrack.h11
-rw-r--r--include/media/IAudioPolicyService.h25
-rw-r--r--media/libmedia/AudioRecord.cpp2
-rw-r--r--media/libmedia/AudioSystem.cpp34
-rw-r--r--media/libmedia/AudioTrack.cpp202
-rw-r--r--media/libmedia/IAudioPolicyService.cpp113
-rw-r--r--services/audioflinger/Threads.cpp12
-rw-r--r--services/audioflinger/Tracks.cpp2
-rw-r--r--services/audiopolicy/AudioPolicyInterface.h23
-rw-r--r--services/audiopolicy/AudioPolicyInterfaceImpl.cpp41
-rw-r--r--services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp49
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp116
-rw-r--r--services/audiopolicy/AudioPolicyManager.h25
-rw-r--r--services/audiopolicy/AudioPolicyService.cpp10
-rw-r--r--services/audiopolicy/AudioPolicyService.h41
17 files changed, 433 insertions, 341 deletions
diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h
index f4afd45..3ed0b74 100644
--- a/include/media/AudioPolicyHelper.h
+++ b/include/media/AudioPolicyHelper.h
@@ -18,7 +18,7 @@
#include <system/audio.h>
-audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)
+static audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)
{
// flags to stream type mapping
if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
@@ -61,4 +61,55 @@ audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *at
}
}
+static void stream_type_to_audio_attributes(audio_stream_type_t streamType,
+ audio_attributes_t *attr) {
+ attr->flags = 0x0;
+
+ switch (streamType) {
+ case AUDIO_STREAM_DEFAULT:
+ case AUDIO_STREAM_MUSIC:
+ attr->content_type = AUDIO_CONTENT_TYPE_MUSIC;
+ attr->usage = AUDIO_USAGE_MEDIA;
+ break;
+ case AUDIO_STREAM_VOICE_CALL:
+ attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ break;
+ case AUDIO_STREAM_ENFORCED_AUDIBLE:
+ attr->flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
+ // intended fall through, attributes in common with STREAM_SYSTEM
+ case AUDIO_STREAM_SYSTEM:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+ break;
+ case AUDIO_STREAM_RING:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+ break;
+ case AUDIO_STREAM_ALARM:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_ALARM;
+ break;
+ case AUDIO_STREAM_NOTIFICATION:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_NOTIFICATION;
+ break;
+ case AUDIO_STREAM_BLUETOOTH_SCO:
+ attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION;
+ attr->flags |= AUDIO_FLAG_SCO;
+ break;
+ case AUDIO_STREAM_DTMF:
+ attr->content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
+ attr->usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+ break;
+ case AUDIO_STREAM_TTS:
+ attr->content_type = AUDIO_CONTENT_TYPE_SPEECH;
+ attr->usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+ break;
+ default:
+ ALOGE("invalid stream type %d when converting to attributes", streamType);
+ }
+}
+
#endif //AUDIO_POLICY_HELPER_H_
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 1614525..7f1afb3 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -215,7 +215,10 @@ public:
audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
const audio_offload_info_t *offloadInfo = NULL);
- static audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr,
+ static status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
uint32_t samplingRate = 0,
audio_format_t format = AUDIO_FORMAT_DEFAULT,
audio_channel_mask_t channelMask = AUDIO_CHANNEL_OUT_STEREO,
@@ -223,11 +226,13 @@ public:
const audio_offload_info_t *offloadInfo = NULL);
static status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session);
+ audio_session_t session);
static status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session);
- static void releaseOutput(audio_io_handle_t output);
+ audio_session_t session);
+ static void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
// Client must successfully hand off the handle reference to AudioFlinger via openRecord(),
// or release it with releaseInput().
@@ -235,7 +240,7 @@ public:
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int sessionId,
+ audio_session_t sessionId,
audio_input_flags_t);
static status_t startInput(audio_io_handle_t input,
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index b5256f0..fd51b8f 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -239,6 +239,9 @@ public:
* Parameters not listed in the AudioTrack constructors above:
*
* threadCanCallJava: Whether callbacks are made from an attached thread and thus can call JNI.
+ *
+ * Internal state post condition:
+ * (mStreamType == AUDIO_STREAM_DEFAULT) implies this AudioTrack has valid attributes
*/
status_t set(audio_stream_type_t streamType,
uint32_t sampleRate,
@@ -273,7 +276,7 @@ public:
/* getters, see constructors and set() */
- audio_stream_type_t streamType() const { return mStreamType; }
+ audio_stream_type_t streamType() const;
audio_format_t format() const { return mFormat; }
/* Return frame size in bytes, which for linear PCM is
@@ -598,9 +601,6 @@ protected:
AudioTrack& operator = (const AudioTrack& other);
void setAttributesFromStreamType(audio_stream_type_t streamType);
- void setStreamTypeFromAttributes(audio_attributes_t& aa);
- /* paa is guaranteed non-NULL */
- bool isValidAttributes(const audio_attributes_t *paa);
/* a small internal class to handle the callback */
class AudioTrackThread : public Thread
@@ -688,7 +688,8 @@ protected:
// constant after constructor or set()
audio_format_t mFormat; // as requested by client, not forced to 16-bit
- audio_stream_type_t mStreamType;
+ audio_stream_type_t mStreamType; // mStreamType == AUDIO_STREAM_DEFAULT implies
+ // this AudioTrack has valid attributes
uint32_t mChannelCount;
audio_channel_mask_t mChannelMask;
sp<IMemory> mSharedBuffer;
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 16fe9cf..2f30304 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -56,24 +56,29 @@ public:
audio_channel_mask_t channelMask = 0,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
const audio_offload_info_t *offloadInfo = NULL) = 0;
- virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate = 0,
- audio_format_t format = AUDIO_FORMAT_DEFAULT,
- audio_channel_mask_t channelMask = 0,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- const audio_offload_info_t *offloadInfo = NULL) = 0;
+ virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate = 0,
+ audio_format_t format = AUDIO_FORMAT_DEFAULT,
+ audio_channel_mask_t channelMask = 0,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL) = 0;
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0) = 0;
+ audio_session_t session) = 0;
virtual status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0) = 0;
- virtual void releaseOutput(audio_io_handle_t output) = 0;
+ audio_session_t session) = 0;
+ virtual void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session) = 0;
virtual audio_io_handle_t getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int audioSession,
+ audio_session_t audioSession,
audio_input_flags_t flags) = 0;
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session) = 0;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 9e7ba88..77437d1 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -445,7 +445,7 @@ status_t AudioRecord::openRecord_l(size_t epoch)
}
audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
- mChannelMask, mSessionId, mFlags);
+ mChannelMask, (audio_session_t)mSessionId, mFlags);
if (input == AUDIO_IO_HANDLE_NONE) {
ALOGE("Could not get audio input for record source %d, sample rate %u, format %#x, "
"channel mask %#x, session %d, flags %#x",
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 1f8e9b6..5f42f25 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -649,22 +649,26 @@ audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream,
return aps->getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
}
-audio_io_handle_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+status_t AudioSystem::getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
- if (attr == NULL) return 0;
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
- if (aps == 0) return 0;
- return aps->getOutputForAttr(attr, samplingRate, format, channelMask, flags, offloadInfo);
+ if (aps == 0) return NO_INIT;
+ return aps->getOutputForAttr(attr, output, session, stream,
+ samplingRate, format, channelMask,
+ flags, offloadInfo);
}
status_t AudioSystem::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
@@ -673,25 +677,27 @@ status_t AudioSystem::startOutput(audio_io_handle_t output,
status_t AudioSystem::stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->stopOutput(output, stream, session);
}
-void AudioSystem::releaseOutput(audio_io_handle_t output)
+void AudioSystem::releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return;
- aps->releaseOutput(output);
+ aps->releaseOutput(output, stream, session);
}
audio_io_handle_t AudioSystem::getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int sessionId,
+ audio_session_t sessionId,
audio_input_flags_t flags)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d6c3bc5..0c69ec2 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -28,6 +28,7 @@
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
#include <media/IAudioFlinger.h>
+#include <media/AudioPolicyHelper.h>
#include <media/AudioResamplerPublic.h>
#define WAIT_PERIOD_MS 10
@@ -278,30 +279,22 @@ status_t AudioTrack::set(
}
// handle default values first.
- // TODO once AudioPolicyManager fully supports audio_attributes_t,
- // remove stream "text-to-speech" redirect
- if ((streamType == AUDIO_STREAM_DEFAULT) || (streamType == AUDIO_STREAM_TTS)) {
+ if (streamType == AUDIO_STREAM_DEFAULT) {
streamType = AUDIO_STREAM_MUSIC;
}
-
if (pAttributes == NULL) {
if (uint32_t(streamType) >= AUDIO_STREAM_PUBLIC_CNT) {
ALOGE("Invalid stream type %d", streamType);
return BAD_VALUE;
}
- setAttributesFromStreamType(streamType);
mStreamType = streamType;
+
} else {
- if (!isValidAttributes(pAttributes)) {
- ALOGE("Invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
- pAttributes->usage, pAttributes->content_type, pAttributes->flags,
- pAttributes->tags);
- }
// stream type shouldn't be looked at, this track has audio attributes
memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
- setStreamTypeFromAttributes(mAttributes);
ALOGV("Building AudioTrack with attributes: usage=%d content=%d flags=0x%x tags=[%s]",
mAttributes.usage, mAttributes.content_type, mAttributes.flags, mAttributes.tags);
+ mStreamType = AUDIO_STREAM_DEFAULT;
}
// these below should probably come from the audioFlinger too...
@@ -341,10 +334,6 @@ status_t AudioTrack::set(
// FIXME why can't we allow direct AND fast?
((flags | AUDIO_OUTPUT_FLAG_DIRECT) & ~AUDIO_OUTPUT_FLAG_FAST);
}
- // only allow deep buffering for music stream type
- if (mStreamType != AUDIO_STREAM_MUSIC) {
- flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
- }
if (flags & AUDIO_OUTPUT_FLAG_DIRECT) {
if (audio_is_linear_pcm(format)) {
@@ -915,24 +904,38 @@ status_t AudioTrack::attachAuxEffect(int effectId)
return status;
}
+audio_stream_type_t AudioTrack::streamType() const
+{
+ if (mStreamType == AUDIO_STREAM_DEFAULT) {
+ return audio_attributes_to_stream_type(&mAttributes);
+ }
+ return mStreamType;
+}
+
// -------------------------------------------------------------------------
// must be called with mLock held
status_t AudioTrack::createTrack_l()
{
- status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
if (audioFlinger == 0) {
ALOGE("Could not get audioflinger");
return NO_INIT;
}
- audio_io_handle_t output = AudioSystem::getOutputForAttr(&mAttributes, mSampleRate, mFormat,
- mChannelMask, mFlags, mOffloadInfo);
- if (output == AUDIO_IO_HANDLE_NONE) {
+ audio_io_handle_t output;
+ audio_stream_type_t streamType = mStreamType;
+ audio_attributes_t *attr = (mStreamType == AUDIO_STREAM_DEFAULT) ? &mAttributes : NULL;
+ status_t status = AudioSystem::getOutputForAttr(attr, &output,
+ (audio_session_t)mSessionId, &streamType,
+ mSampleRate, mFormat, mChannelMask,
+ mFlags, mOffloadInfo);
+
+
+ if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) {
ALOGE("Could not get audio output for stream type %d, usage %d, sample rate %u, format %#x,"
" channel mask %#x, flags %#x",
- mStreamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
+ streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
return BAD_VALUE;
}
{
@@ -1086,7 +1089,7 @@ status_t AudioTrack::createTrack_l()
size_t temp = frameCount; // temp may be replaced by a revised value of frameCount,
// but we will still need the original value also
- sp<IAudioTrack> track = audioFlinger->createTrack(mStreamType,
+ sp<IAudioTrack> track = audioFlinger->createTrack(streamType,
mSampleRate,
// AudioFlinger only sees 16-bit PCM
mFormat == AUDIO_FORMAT_PCM_8_BIT &&
@@ -1232,7 +1235,7 @@ status_t AudioTrack::createTrack_l()
}
release:
- AudioSystem::releaseOutput(output);
+ AudioSystem::releaseOutput(output, streamType, (audio_session_t)mSessionId);
if (status == NO_ERROR) {
status = NO_INIT;
}
@@ -2066,161 +2069,6 @@ uint32_t AudioTrack::getUnderrunFrames() const
return mProxy->getUnderrunFrames();
}
-void AudioTrack::setAttributesFromStreamType(audio_stream_type_t streamType) {
- mAttributes.flags = 0x0;
-
- switch(streamType) {
- case AUDIO_STREAM_DEFAULT:
- case AUDIO_STREAM_MUSIC:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_MUSIC;
- mAttributes.usage = AUDIO_USAGE_MEDIA;
- break;
- case AUDIO_STREAM_VOICE_CALL:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
- mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
- break;
- case AUDIO_STREAM_ENFORCED_AUDIBLE:
- mAttributes.flags |= AUDIO_FLAG_AUDIBILITY_ENFORCED;
- // intended fall through, attributes in common with STREAM_SYSTEM
- case AUDIO_STREAM_SYSTEM:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- mAttributes.usage = AUDIO_USAGE_ASSISTANCE_SONIFICATION;
- break;
- case AUDIO_STREAM_RING:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- mAttributes.usage = AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
- break;
- case AUDIO_STREAM_ALARM:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- mAttributes.usage = AUDIO_USAGE_ALARM;
- break;
- case AUDIO_STREAM_NOTIFICATION:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- mAttributes.usage = AUDIO_USAGE_NOTIFICATION;
- break;
- case AUDIO_STREAM_BLUETOOTH_SCO:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
- mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION;
- mAttributes.flags |= AUDIO_FLAG_SCO;
- break;
- case AUDIO_STREAM_DTMF:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SONIFICATION;
- mAttributes.usage = AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
- break;
- case AUDIO_STREAM_TTS:
- mAttributes.content_type = AUDIO_CONTENT_TYPE_SPEECH;
- mAttributes.usage = AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
- break;
- default:
- ALOGE("invalid stream type %d when converting to attributes", streamType);
- }
-}
-
-void AudioTrack::setStreamTypeFromAttributes(audio_attributes_t& aa) {
- // flags to stream type mapping
- if ((aa.flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
- mStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
- return;
- }
- if ((aa.flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
- mStreamType = AUDIO_STREAM_BLUETOOTH_SCO;
- return;
- }
- // TODO once AudioPolicyManager fully supports audio_attributes_t,
- // remove stream remap, the flag will be enough
- if ((aa.flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
- mStreamType = AUDIO_STREAM_TTS;
- return;
- }
-
- // usage to stream type mapping
- switch (aa.usage) {
- case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: {
- // TODO once AudioPolicyManager fully supports audio_attributes_t,
- // remove stream change based on stream activity
- bool active;
- status_t status = AudioSystem::isStreamActive(AUDIO_STREAM_RING, &active, 0);
- if (status == NO_ERROR && active == true) {
- mStreamType = AUDIO_STREAM_RING;
- break;
- }
- status = AudioSystem::isStreamActive(AUDIO_STREAM_ALARM, &active, 0);
- if (status == NO_ERROR && active == true) {
- mStreamType = AUDIO_STREAM_ALARM;
- break;
- }
- audio_mode_t phoneState = AudioSystem::getPhoneState();
- if (phoneState == AUDIO_MODE_IN_CALL || phoneState == AUDIO_MODE_IN_COMMUNICATION) {
- mStreamType = AUDIO_STREAM_VOICE_CALL;
- break;
- }
- } /// FALL THROUGH
- case AUDIO_USAGE_MEDIA:
- case AUDIO_USAGE_GAME:
- case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
- mStreamType = AUDIO_STREAM_MUSIC;
- return;
- case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
- mStreamType = AUDIO_STREAM_SYSTEM;
- return;
- case AUDIO_USAGE_VOICE_COMMUNICATION:
- mStreamType = AUDIO_STREAM_VOICE_CALL;
- return;
-
- case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
- mStreamType = AUDIO_STREAM_DTMF;
- return;
-
- case AUDIO_USAGE_ALARM:
- mStreamType = AUDIO_STREAM_ALARM;
- return;
- case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
- mStreamType = AUDIO_STREAM_RING;
- return;
-
- case AUDIO_USAGE_NOTIFICATION:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
- case AUDIO_USAGE_NOTIFICATION_EVENT:
- mStreamType = AUDIO_STREAM_NOTIFICATION;
- return;
-
- case AUDIO_USAGE_UNKNOWN:
- default:
- mStreamType = AUDIO_STREAM_MUSIC;
- }
-}
-
-bool AudioTrack::isValidAttributes(const audio_attributes_t *paa) {
- // has flags that map to a strategy?
- if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
- return true;
- }
-
- // has known usage?
- switch (paa->usage) {
- case AUDIO_USAGE_UNKNOWN:
- case AUDIO_USAGE_MEDIA:
- case AUDIO_USAGE_VOICE_COMMUNICATION:
- case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
- case AUDIO_USAGE_ALARM:
- case AUDIO_USAGE_NOTIFICATION:
- case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
- case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
- case AUDIO_USAGE_NOTIFICATION_EVENT:
- case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
- case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
- case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
- case AUDIO_USAGE_GAME:
- break;
- default:
- return false;
- }
- return true;
-}
// =========================================================================
void AudioTrack::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 89178f1..5f83a0d 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -160,21 +160,45 @@ public:
return static_cast <audio_io_handle_t> (reply.readInt32());
}
- virtual audio_io_handle_t getOutputForAttr(
- const audio_attributes_t *attr,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+ virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
if (attr == NULL) {
- ALOGE("Writing NULL audio attributes - shouldn't happen");
- return (audio_io_handle_t) 0;
+ if (stream == NULL) {
+ ALOGE("getOutputForAttr(): NULL audio attributes and stream type");
+ return BAD_VALUE;
+ }
+ if (*stream == AUDIO_STREAM_DEFAULT) {
+ ALOGE("getOutputForAttr unspecified stream type");
+ return BAD_VALUE;
+ }
+ }
+ if (output == NULL) {
+ ALOGE("getOutputForAttr NULL output - shouldn't happen");
+ return BAD_VALUE;
+ }
+ if (attr == NULL) {
+ data.writeInt32(0);
+ } else {
+ data.writeInt32(1);
+ data.write(attr, sizeof(audio_attributes_t));
+ }
+ data.writeInt32(session);
+ if (stream == NULL) {
+ data.writeInt32(0);
+ } else {
+ data.writeInt32(1);
+ data.writeInt32(*stream);
}
- data.write(attr, sizeof(audio_attributes_t));
data.writeInt32(samplingRate);
data.writeInt32(static_cast <uint32_t>(format));
data.writeInt32(channelMask);
@@ -186,41 +210,56 @@ public:
data.writeInt32(1);
data.write(offloadInfo, sizeof(audio_offload_info_t));
}
- remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);
- return static_cast <audio_io_handle_t> (reply.readInt32());
+ status_t status = remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ status = (status_t)reply.readInt32();
+ if (status != NO_ERROR) {
+ return status;
+ }
+ *output = (audio_io_handle_t)reply.readInt32();
+ if (stream != NULL) {
+ *stream = (audio_stream_type_t)reply.readInt32();
+ }
+ return status;
}
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(output);
data.writeInt32((int32_t) stream);
- data.writeInt32(session);
+ data.writeInt32((int32_t)session);
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,
- int session)
+ audio_session_t session)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(output);
data.writeInt32((int32_t) stream);
- data.writeInt32(session);
+ data.writeInt32((int32_t)session);
remote()->transact(STOP_OUTPUT, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
- virtual void releaseOutput(audio_io_handle_t output)
+ virtual void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(output);
+ data.writeInt32((int32_t)stream);
+ data.writeInt32((int32_t)session);
remote()->transact(RELEASE_OUTPUT, data, &reply);
}
@@ -229,7 +268,7 @@ public:
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int audioSession,
+ audio_session_t audioSession,
audio_input_flags_t flags)
{
Parcel data, reply;
@@ -238,7 +277,7 @@ public:
data.writeInt32(samplingRate);
data.writeInt32(static_cast <uint32_t>(format));
data.writeInt32(channelMask);
- data.writeInt32(audioSession);
+ data.writeInt32((int32_t)audioSession);
data.writeInt32(flags);
remote()->transact(GET_INPUT, data, &reply);
return static_cast <audio_io_handle_t> (reply.readInt32());
@@ -706,7 +745,16 @@ status_t BnAudioPolicyService::onTransact(
case GET_OUTPUT_FOR_ATTR: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_attributes_t attr;
- data.read(&attr, sizeof(audio_attributes_t));
+ bool hasAttributes = data.readInt32() != 0;
+ if (hasAttributes) {
+ data.read(&attr, sizeof(audio_attributes_t));
+ }
+ audio_session_t session = (audio_session_t)data.readInt32();
+ audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
+ bool hasStream = data.readInt32() != 0;
+ if (hasStream) {
+ stream = (audio_stream_type_t)data.readInt32();
+ }
uint32_t samplingRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
@@ -717,13 +765,14 @@ status_t BnAudioPolicyService::onTransact(
if (hasOffloadInfo) {
data.read(&offloadInfo, sizeof(audio_offload_info_t));
}
- audio_io_handle_t output = getOutputForAttr(&attr,
- samplingRate,
- format,
- channelMask,
- flags,
- hasOffloadInfo ? &offloadInfo : NULL);
- reply->writeInt32(static_cast <int>(output));
+ audio_io_handle_t output;
+ status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
+ &output, session, &stream,
+ samplingRate, format, channelMask,
+ flags, hasOffloadInfo ? &offloadInfo : NULL);
+ reply->writeInt32(status);
+ reply->writeInt32(output);
+ reply->writeInt32(stream);
return NO_ERROR;
} break;
@@ -732,7 +781,7 @@ status_t BnAudioPolicyService::onTransact(
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());
- int session = data.readInt32();
+ audio_session_t session = (audio_session_t)data.readInt32();
reply->writeInt32(static_cast <uint32_t>(startOutput(output,
stream,
session)));
@@ -744,7 +793,7 @@ status_t BnAudioPolicyService::onTransact(
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());
- int session = data.readInt32();
+ audio_session_t session = (audio_session_t)data.readInt32();
reply->writeInt32(static_cast <uint32_t>(stopOutput(output,
stream,
session)));
@@ -754,7 +803,9 @@ status_t BnAudioPolicyService::onTransact(
case RELEASE_OUTPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32());
- releaseOutput(output);
+ audio_stream_type_t stream = (audio_stream_type_t)data.readInt32();
+ audio_session_t session = (audio_session_t)data.readInt32();
+ releaseOutput(output, stream, session);
return NO_ERROR;
} break;
@@ -764,7 +815,7 @@ status_t BnAudioPolicyService::onTransact(
uint32_t samplingRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- int audioSession = data.readInt32();
+ audio_session_t audioSession = (audio_session_t)data.readInt32();
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
audio_io_handle_t input = getInput(inputSource,
samplingRate,
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 792419f..08d9eb1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1622,13 +1622,15 @@ 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(mId, track->streamType(),
+ (audio_session_t)track->sessionId());
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(mId, track->streamType(),
+ (audio_session_t)track->sessionId());
mLock.lock();
}
return INVALID_OPERATION;
@@ -2057,13 +2059,15 @@ 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(mId, track->streamType(),
+ (audio_session_t)track->sessionId());
#ifdef ADD_BATTERY_DATA
// to track the speaker usage
addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
#endif
if (track->isTerminated()) {
- AudioSystem::releaseOutput(mId);
+ AudioSystem::releaseOutput(mId, track->streamType(),
+ (audio_session_t)track->sessionId());
}
}
}
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index aa708ec..fcbf8f8 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -491,7 +491,7 @@ void AudioFlinger::PlaybackThread::Track::destroy()
wasActive = playbackThread->destroyTrack_l(this);
}
if (isExternalTrack() && !wasActive) {
- AudioSystem::releaseOutput(mThreadIoHandle);
+ AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, (audio_session_t)mSessionId);
}
}
}
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 5524463..f7ffb6d 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -90,22 +90,27 @@ public:
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo) = 0;
- virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo) = 0;
+ virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo) = 0;
// indicates to the audio policy manager that the output starts being used by corresponding stream.
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0) = 0;
+ audio_session_t session) = 0;
// indicates to the audio policy manager that the output stops being used by corresponding stream.
virtual status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0) = 0;
+ audio_session_t session) = 0;
// releases the output.
- virtual void releaseOutput(audio_io_handle_t output) = 0;
+ virtual void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session) = 0;
// request an input appropriate for record from the supplied device with supplied parameters.
virtual audio_io_handle_t getInput(audio_source_t inputSource,
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index 710a905..8b64d5b 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -141,25 +141,28 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
format, channelMask, flags, offloadInfo);
}
-audio_io_handle_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
if (mAudioPolicyManager == NULL) {
- return 0;
+ return NO_INIT;
}
ALOGV("getOutput()");
Mutex::Autolock _l(mLock);
- return mAudioPolicyManager->getOutputForAttr(attr, samplingRate,
+ return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, samplingRate,
format, channelMask, flags, offloadInfo);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
@@ -186,7 +189,7 @@ status_t AudioPolicyService::startOutput(audio_io_handle_t output,
status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
@@ -201,7 +204,7 @@ status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
status_t AudioPolicyService::doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
ALOGV("doStopOutput from tid %d", gettid());
sp<AudioPolicyEffects>audioPolicyEffects;
@@ -220,27 +223,31 @@ status_t AudioPolicyService::doStopOutput(audio_io_handle_t output,
return mAudioPolicyManager->stopOutput(output, stream, session);
}
-void AudioPolicyService::releaseOutput(audio_io_handle_t output)
+void AudioPolicyService::releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session)
{
if (mAudioPolicyManager == NULL) {
return;
}
ALOGV("releaseOutput()");
- mOutputCommandThread->releaseOutputCommand(output);
+ mOutputCommandThread->releaseOutputCommand(output, stream, session);
}
-void AudioPolicyService::doReleaseOutput(audio_io_handle_t output)
+void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session)
{
ALOGV("doReleaseOutput from tid %d", gettid());
Mutex::Autolock _l(mLock);
- mAudioPolicyManager->releaseOutput(output);
+ mAudioPolicyManager->releaseOutput(output, stream, session);
}
audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int audioSession,
+ audio_session_t audioSession,
audio_input_flags_t flags)
{
if (mAudioPolicyManager == NULL) {
@@ -263,7 +270,7 @@ audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
// the audio_in_acoustics_t parameter is ignored by get_input()
input = mAudioPolicyManager->getInput(inputSource, samplingRate,
format, channelMask,
- (audio_session_t)audioSession, flags);
+ audioSession, flags);
audioPolicyEffects = mAudioPolicyEffects;
}
if (input == 0) {
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index ac61cb2..694dea3 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -148,7 +148,7 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
@@ -176,7 +176,7 @@ status_t AudioPolicyService::startOutput(audio_io_handle_t output,
status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
@@ -191,7 +191,7 @@ status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
status_t AudioPolicyService::doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
ALOGV("doStopOutput from tid %d", gettid());
// release audio processors from the stream
@@ -210,16 +210,20 @@ status_t AudioPolicyService::doStopOutput(audio_io_handle_t output,
return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
}
-void AudioPolicyService::releaseOutput(audio_io_handle_t output)
+void AudioPolicyService::releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session)
{
if (mpAudioPolicy == NULL) {
return;
}
ALOGV("releaseOutput()");
- mOutputCommandThread->releaseOutputCommand(output);
+ mOutputCommandThread->releaseOutputCommand(output, stream, session);
}
-void AudioPolicyService::doReleaseOutput(audio_io_handle_t output)
+void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream __unused,
+ audio_session_t session __unused)
{
ALOGV("doReleaseOutput from tid %d", gettid());
Mutex::Autolock _l(mLock);
@@ -230,7 +234,7 @@ audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int audioSession,
+ audio_session_t audioSession,
audio_input_flags_t flags __unused)
{
if (mpAudioPolicy == NULL) {
@@ -549,16 +553,29 @@ status_t AudioPolicyService::setAudioPortConfig(const struct audio_port_config *
return INVALID_OPERATION;
}
-audio_io_handle_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
{
- audio_stream_type_t stream = audio_attributes_to_stream_type(attr);
-
- return getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
+ if (attr != NULL) {
+ *stream = audio_attributes_to_stream_type(attr);
+ } else {
+ if (*stream == AUDIO_STREAM_DEFAULT) {
+ return BAD_VALUE;
+ }
+ }
+ *output = getOutput(*stream, samplingRate, format, channelMask,
+ flags, offloadInfo);
+ if (*output == AUDIO_IO_HANDLE_NONE) {
+ return INVALID_OPERATION;
+ }
+ return NO_ERROR;
}
status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session __unused,
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 1631d6c..8ca0b96 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -43,6 +43,7 @@
#include <hardware/audio.h>
#include <hardware/audio_effect.h>
#include <media/AudioParameter.h>
+#include <media/AudioPolicyHelper.h>
#include <soundtrigger/SoundTrigger.h>
#include "AudioPolicyManager.h"
#include "audio_policy_conf.h"
@@ -841,42 +842,65 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
device, stream, samplingRate, format, channelMask, flags);
- return getOutputForDevice(device, stream, samplingRate,format, channelMask, flags,
- offloadInfo);
-}
-
-audio_io_handle_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
-{
- if (attr == NULL) {
- ALOGE("getOutputForAttr() called with NULL audio attributes");
- return 0;
+ return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE,
+ stream, samplingRate,format, channelMask,
+ flags, offloadInfo);
+}
+
+status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
+{
+ audio_attributes_t attributes;
+ if (attr != NULL) {
+ if (!isValidAttributes(attr)) {
+ ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
+ attr->usage, attr->content_type, attr->flags,
+ attr->tags);
+ return BAD_VALUE;
+ }
+ attributes = *attr;
+ } else {
+ if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
+ ALOGE("getOutputForAttr(): invalid stream type");
+ return BAD_VALUE;
+ }
+ stream_type_to_audio_attributes(*stream, &attributes);
}
+
ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x",
- attr->usage, attr->content_type, attr->tags, attr->flags);
+ attributes.usage, attributes.content_type, attributes.tags, attributes.flags);
// TODO this is where filtering for custom policies (rerouting, dynamic sources) will go
- routing_strategy strategy = (routing_strategy) getStrategyForAttr(attr);
+ routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
- if ((attr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
+ if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
}
ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
device, samplingRate, format, channelMask, flags);
- audio_stream_type_t stream = streamTypefromAttributesInt(attr);
- return getOutputForDevice(device, stream, samplingRate, format, channelMask, flags,
- offloadInfo);
+ *stream = streamTypefromAttributesInt(&attributes);
+ *output = getOutputForDevice(device, session, *stream,
+ samplingRate, format, channelMask,
+ flags, offloadInfo);
+ if (*output == AUDIO_IO_HANDLE_NONE) {
+ return INVALID_OPERATION;
+ }
+ return NO_ERROR;
}
audio_io_handle_t AudioPolicyManager::getOutputForDevice(
audio_devices_t device,
+ audio_session_t session,
audio_stream_type_t stream,
uint32_t samplingRate,
audio_format_t format,
@@ -939,6 +963,10 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevice(
if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
}
+ // only allow deep buffering for music stream type
+ if (stream != AUDIO_STREAM_MUSIC) {
+ flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
+ }
sp<IOProfile> profile;
@@ -1123,7 +1151,7 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h
status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
ssize_t index = mOutputs.indexOfKey(output);
@@ -1207,7 +1235,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
ssize_t index = mOutputs.indexOfKey(output);
@@ -1265,7 +1293,9 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
}
}
-void AudioPolicyManager::releaseOutput(audio_io_handle_t output)
+void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session)
{
ALOGV("releaseOutput() %d", output);
ssize_t index = mOutputs.indexOfKey(output);
@@ -7494,6 +7524,15 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_
case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
return AUDIO_STREAM_MUSIC;
case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ if (isStreamActive(AUDIO_STREAM_ALARM)) {
+ return AUDIO_STREAM_ALARM;
+ }
+ if (isStreamActive(AUDIO_STREAM_RING)) {
+ return AUDIO_STREAM_RING;
+ }
+ if (isInCall()) {
+ return AUDIO_STREAM_VOICE_CALL;
+ }
return AUDIO_STREAM_ACCESSIBILITY;
case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
return AUDIO_STREAM_SYSTEM;
@@ -7520,4 +7559,35 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_
return AUDIO_STREAM_MUSIC;
}
}
+
+bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa) {
+ // has flags that map to a strategy?
+ if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
+ return true;
+ }
+
+ // has known usage?
+ switch (paa->usage) {
+ case AUDIO_USAGE_UNKNOWN:
+ case AUDIO_USAGE_MEDIA:
+ case AUDIO_USAGE_VOICE_COMMUNICATION:
+ case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
+ case AUDIO_USAGE_ALARM:
+ case AUDIO_USAGE_NOTIFICATION:
+ case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+ case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+ case AUDIO_USAGE_NOTIFICATION_EVENT:
+ case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+ case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
+ case AUDIO_USAGE_GAME:
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
}; // namespace android
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 7af6475..6eb2163 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -87,19 +87,24 @@ public:
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo);
- virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo);
+ virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate,
+ audio_format_t format,
+ audio_channel_mask_t channelMask,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0);
+ audio_session_t session);
virtual status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0);
- virtual void releaseOutput(audio_io_handle_t output);
+ audio_session_t session);
+ virtual void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
virtual audio_io_handle_t getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
@@ -862,6 +867,7 @@ private:
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevice(
audio_devices_t device,
+ audio_session_t session,
audio_stream_type_t stream,
uint32_t samplingRate,
audio_format_t format,
@@ -877,6 +883,7 @@ private:
// the mute/unmute happened
uint32_t handleEventForBeacon(int event);
uint32_t setBeaconMute(bool mute);
+ bool isValidAttributes(const audio_attributes_t *paa);
};
};
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp
index 6a4a669..8a9abc9 100644
--- a/services/audiopolicy/AudioPolicyService.cpp
+++ b/services/audiopolicy/AudioPolicyService.cpp
@@ -457,7 +457,7 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
break;
}
mLock.unlock();
- svc->doReleaseOutput(data->mIO);
+ svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
mLock.lock();
}break;
case CREATE_AUDIO_PATCH: {
@@ -654,7 +654,7 @@ status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume
void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
audio_stream_type_t stream,
- int session)
+ audio_session_t session)
{
sp<AudioCommand> command = new AudioCommand();
command->mCommand = STOP_OUTPUT;
@@ -667,12 +667,16 @@ void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t
sendCommand(command);
}
-void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output)
+void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session)
{
sp<AudioCommand> command = new AudioCommand();
command->mCommand = RELEASE_OUTPUT;
sp<ReleaseOutputData> data = new ReleaseOutputData();
data->mIO = output;
+ data->mStream = stream;
+ data->mSession = session;
command->mParam = data;
ALOGV("AudioCommandThread() adding release output %d", output);
sendCommand(command);
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index f1db309..b8171d6 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -72,24 +72,29 @@ public:
audio_output_flags_t flags =
AUDIO_OUTPUT_FLAG_NONE,
const audio_offload_info_t *offloadInfo = NULL);
- virtual audio_io_handle_t getOutputForAttr(const audio_attributes_t *attr,
- uint32_t samplingRate = 0,
- audio_format_t format = AUDIO_FORMAT_DEFAULT,
- audio_channel_mask_t channelMask = 0,
- audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- const audio_offload_info_t *offloadInfo = NULL);
+ virtual status_t getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uint32_t samplingRate = 0,
+ audio_format_t format = AUDIO_FORMAT_DEFAULT,
+ audio_channel_mask_t channelMask = 0,
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
+ const audio_offload_info_t *offloadInfo = NULL);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0);
+ audio_session_t session);
virtual status_t stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0);
- virtual void releaseOutput(audio_io_handle_t output);
+ audio_session_t session);
+ virtual void releaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
virtual audio_io_handle_t getInput(audio_source_t inputSource,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- int audioSession,
+ audio_session_t audioSession,
audio_input_flags_t flags);
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session);
@@ -181,8 +186,10 @@ public:
status_t doStopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
- int session = 0);
- void doReleaseOutput(audio_io_handle_t output);
+ audio_session_t session);
+ void doReleaseOutput(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
status_t clientCreateAudioPatch(const struct audio_patch *patch,
audio_patch_handle_t *handle,
@@ -250,8 +257,10 @@ private:
status_t voiceVolumeCommand(float volume, int delayMs = 0);
void stopOutputCommand(audio_io_handle_t output,
audio_stream_type_t stream,
- int session);
- void releaseOutputCommand(audio_io_handle_t output);
+ audio_session_t session);
+ void releaseOutputCommand(audio_io_handle_t output,
+ audio_stream_type_t stream,
+ audio_session_t session);
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,
@@ -321,12 +330,14 @@ private:
public:
audio_io_handle_t mIO;
audio_stream_type_t mStream;
- int mSession;
+ audio_session_t mSession;
};
class ReleaseOutputData : public AudioCommandData {
public:
audio_io_handle_t mIO;
+ audio_stream_type_t mStream;
+ audio_session_t mSession;
};
class CreateAudioPatchData : public AudioCommandData {