summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2014-11-11 13:43:36 -0800
committerEric Laurent <elaurent@google.com>2014-11-21 10:41:13 -0800
commit223fd5c9738e9665e495904d37d4632414b68c1e (patch)
tree33e0afab9a7479cdc4c688a742a8977c8ead21e4 /services
parentbc0f452b9a76dd8c8244e775bc9c5aa85cae3ddf (diff)
downloadframeworks_av-223fd5c9738e9665e495904d37d4632414b68c1e.zip
frameworks_av-223fd5c9738e9665e495904d37d4632414b68c1e.tar.gz
frameworks_av-223fd5c9738e9665e495904d37d4632414b68c1e.tar.bz2
audio: new routing strategies and stream types
Added new routing strategies and stream type for internal use by audio policy manager and audio flinger: - One for accessibility to allow different routing than media - One for re-routing (remote submix) in preparation of dynamic policies - Added stream type for "internal" audio flinger tracks used for audio patches and duplication. Bug: 18067208. Change-Id: I88f884b552e51e4a49c29125e5a1204cf58ff434
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp37
-rw-r--r--services/audioflinger/AudioFlinger.h2
-rw-r--r--services/audioflinger/Threads.cpp7
-rw-r--r--services/audioflinger/Threads.h4
-rw-r--r--services/audioflinger/Tracks.cpp8
-rw-r--r--services/audiopolicy/AudioPolicyEffects.cpp13
-rw-r--r--services/audiopolicy/AudioPolicyEffects.h2
-rw-r--r--services/audiopolicy/AudioPolicyInterfaceImpl.cpp16
-rw-r--r--services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp28
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp103
-rw-r--r--services/audiopolicy/AudioPolicyManager.h3
11 files changed, 170 insertions, 53 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ea9d7d3..8acfc07 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -891,6 +891,21 @@ bool AudioFlinger::masterMute_l() const
return mMasterMute;
}
+status_t AudioFlinger::checkStreamType(audio_stream_type_t stream) const
+{
+ if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ ALOGW("setStreamVolume() invalid stream %d", stream);
+ return BAD_VALUE;
+ }
+ pid_t caller = IPCThreadState::self()->getCallingPid();
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT && caller != getpid_cached) {
+ ALOGW("setStreamVolume() pid %d cannot use internal stream type %d", caller, stream);
+ return PERMISSION_DENIED;
+ }
+
+ return NO_ERROR;
+}
+
status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
audio_io_handle_t output)
{
@@ -899,10 +914,11 @@ status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
return PERMISSION_DENIED;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
- ALOGE("setStreamVolume() invalid stream %d", stream);
- return BAD_VALUE;
+ status_t status = checkStreamType(stream);
+ if (status != NO_ERROR) {
+ return status;
}
+ ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to change AUDIO_STREAM_PATCH volume");
AutoMutex lock(mLock);
PlaybackThread *thread = NULL;
@@ -933,8 +949,13 @@ status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
return PERMISSION_DENIED;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT ||
- uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
+ status_t status = checkStreamType(stream);
+ if (status != NO_ERROR) {
+ return status;
+ }
+ ALOG_ASSERT(stream != AUDIO_STREAM_PATCH, "attempt to mute AUDIO_STREAM_PATCH");
+
+ if (uint32_t(stream) == AUDIO_STREAM_ENFORCED_AUDIBLE) {
ALOGE("setStreamMute() invalid stream %d", stream);
return BAD_VALUE;
}
@@ -949,7 +970,8 @@ status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
float AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ status_t status = checkStreamType(stream);
+ if (status != NO_ERROR) {
return 0.0f;
}
@@ -970,7 +992,8 @@ float AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t o
bool AudioFlinger::streamMute(audio_stream_type_t stream) const
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ status_t status = checkStreamType(stream);
+ if (status != NO_ERROR) {
return true;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 4fb372d..aa0af1f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -745,6 +745,8 @@ private:
void closeInputInternal_l(sp<RecordThread> thread);
void setAudioHwSyncForSession_l(PlaybackThread *thread, audio_session_t sessionId);
+ status_t checkStreamType(audio_stream_type_t stream) const;
+
#ifdef TEE_SINK
// all record threads serially share a common tee sink, which is re-created on format change
sp<NBAIO_Sink> mRecordTeeSink;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0f11b34..792419f 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -1224,15 +1224,12 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
readOutputParameters_l();
- // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor
- // There is no AUDIO_STREAM_MIN, and ++ operator does not compile
+ // ++ operator does not compile
for (audio_stream_type_t stream = AUDIO_STREAM_MIN; stream < AUDIO_STREAM_CNT;
stream = (audio_stream_type_t) (stream + 1)) {
mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream);
mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);
}
- // mStreamTypes[AUDIO_STREAM_CNT] exists but isn't explicitly initialized here,
- // because mAudioFlinger doesn't have one to copy from
}
AudioFlinger::PlaybackThread::~PlaybackThread()
@@ -4746,7 +4743,7 @@ void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
frameCount,
IPCThreadState::self()->getCallingUid());
if (outputTrack->cblk() != NULL) {
- thread->setStreamVolume(AUDIO_STREAM_CNT, 1.0f);
+ thread->setStreamVolume(AUDIO_STREAM_PATCH, 1.0f);
mOutputTracks.add(outputTrack);
ALOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
updateWaitTime_l();
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index bb9aa18..119e495 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -727,9 +727,7 @@ private:
void dumpTracks(int fd, const Vector<String16>& args);
SortedVector< sp<Track> > mTracks;
- // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by
- // DuplicatingThread
- stream_type_t mStreamTypes[AUDIO_STREAM_CNT + 1];
+ stream_type_t mStreamTypes[AUDIO_STREAM_CNT];
AudioStreamOut *mOutput;
float mMasterVolume;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 037c73b..aa708ec 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1657,8 +1657,9 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
audio_channel_mask_t channelMask,
size_t frameCount,
int uid)
- : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
- NULL, 0, 0, uid, IAudioFlinger::TRACK_DEFAULT, TYPE_OUTPUT),
+ : Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
+ sampleRate, format, channelMask, frameCount,
+ NULL, 0, 0, uid, IAudioFlinger::TRACK_DEFAULT, TYPE_OUTPUT),
mActive(false), mSourceThread(sourceThread), mClientProxy(NULL)
{
@@ -1873,7 +1874,8 @@ AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThr
size_t frameCount,
void *buffer,
IAudioFlinger::track_flags_t flags)
- : Track(playbackThread, NULL, AUDIO_STREAM_CNT, sampleRate, format, channelMask, frameCount,
+ : Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
+ sampleRate, format, channelMask, frameCount,
buffer, 0, 0, getuid(), flags, TYPE_PATCH),
mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
{
diff --git a/services/audiopolicy/AudioPolicyEffects.cpp b/services/audiopolicy/AudioPolicyEffects.cpp
index e7e1b36..4fbe042 100644
--- a/services/audiopolicy/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/AudioPolicyEffects.cpp
@@ -226,6 +226,11 @@ status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
Mutex::Autolock _l(mLock);
// create audio processors according to stream
+ // FIXME: should we have specific post processing settings for internal streams?
+ // default to media for now.
+ if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
+ stream = AUDIO_STREAM_MUSIC;
+ }
ssize_t index = mOutputStreams.indexOfKey(stream);
if (index < 0) {
ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
@@ -335,7 +340,7 @@ void AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)
return (audio_source_t)i;
}
-const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_CNT+1] = {
+const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = {
AUDIO_STREAM_DEFAULT_TAG,
AUDIO_STREAM_VOICE_CALL_TAG,
AUDIO_STREAM_SYSTEM_TAG,
@@ -350,11 +355,11 @@ const char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_CNT+1] = {
};
// returns the audio_stream_t enum corresponding to the output stream name or
-// AUDIO_STREAM_CNT is no match found
+// AUDIO_STREAM_PUBLIC_CNT is no match found
audio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name)
{
int i;
- for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_CNT; i++) {
+ for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) {
if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) {
ALOGV("streamNameToEnum found stream %s %d", name, i);
break;
@@ -585,7 +590,7 @@ status_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root,
node = node->first_child;
while (node) {
audio_stream_type_t stream = streamNameToEnum(node->name);
- if (stream == AUDIO_STREAM_CNT) {
+ if (stream == AUDIO_STREAM_PUBLIC_CNT) {
ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name);
node = node->next;
continue;
diff --git a/services/audiopolicy/AudioPolicyEffects.h b/services/audiopolicy/AudioPolicyEffects.h
index 6b0d538..3dec437 100644
--- a/services/audiopolicy/AudioPolicyEffects.h
+++ b/services/audiopolicy/AudioPolicyEffects.h
@@ -151,7 +151,7 @@ private:
static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1];
static audio_source_t inputSourceNameToEnum(const char *name);
- static const char *kStreamNames[AUDIO_STREAM_CNT+1]; //+1 required as streams start from -1
+ static const char *kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1]; //+1 required as streams start from -1
audio_stream_type_t streamNameToEnum(const char *name);
// Parse audio_effects.conf
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index c06ca72..710a905 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -129,7 +129,7 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return AUDIO_IO_HANDLE_NONE;
}
if (mAudioPolicyManager == NULL) {
@@ -332,7 +332,7 @@ status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
@@ -350,7 +350,7 @@ status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
@@ -366,7 +366,7 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
@@ -377,7 +377,7 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return 0;
}
if (mAudioPolicyManager == NULL) {
@@ -390,7 +390,7 @@ uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return AUDIO_DEVICE_NONE;
}
if (mAudioPolicyManager == NULL) {
@@ -439,7 +439,7 @@ status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return false;
}
if (mAudioPolicyManager == NULL) {
@@ -451,7 +451,7 @@ bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inP
bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return false;
}
if (mAudioPolicyManager == NULL) {
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 09476c1..ac61cb2 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -134,7 +134,7 @@ audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return AUDIO_IO_HANDLE_NONE;
}
if (mpAudioPolicy == NULL) {
@@ -150,7 +150,7 @@ status_t AudioPolicyService::startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
if (mpAudioPolicy == NULL) {
@@ -178,7 +178,7 @@ status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
audio_stream_type_t stream,
int session)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
if (mpAudioPolicy == NULL) {
@@ -324,7 +324,7 @@ status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
@@ -342,7 +342,7 @@ status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
@@ -363,7 +363,7 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
if (mpAudioPolicy == NULL) {
return NO_INIT;
}
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
@@ -379,7 +379,7 @@ status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return 0;
}
if (mpAudioPolicy == NULL) {
@@ -392,7 +392,7 @@ uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return AUDIO_DEVICE_NONE;
}
if (mpAudioPolicy == NULL) {
@@ -441,7 +441,7 @@ status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return false;
}
if (mpAudioPolicy == NULL) {
@@ -453,7 +453,7 @@ bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inP
bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
{
- if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
+ if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
return false;
}
if (mpAudioPolicy == NULL) {
@@ -561,14 +561,14 @@ audio_io_handle_t AudioPolicyService::getOutputForAttr(const audio_attributes_t
return getOutput(stream, samplingRate, format, channelMask, flags, offloadInfo);
}
-status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session,
- audio_io_handle_t *ioHandle,
- audio_devices_t *device)
+status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session __unused,
+ audio_io_handle_t *ioHandle __unused,
+ audio_devices_t *device __unused)
{
return INVALID_OPERATION;
}
-status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session)
+status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session __unused)
{
return INVALID_OPERATION;
}
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 20a72b0..78ba23d 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -584,6 +584,9 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
if (isInCall()) {
ALOGV("setPhoneState() in call state management: new state is %d", state);
for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
+ if (stream == AUDIO_STREAM_PATCH) {
+ continue;
+ }
handleIncallSonification((audio_stream_type_t)stream, false, true);
}
}
@@ -681,6 +684,9 @@ void AudioPolicyManager::setPhoneState(audio_mode_t state)
if (isStateInCall(state)) {
ALOGV("setPhoneState() in call state management: new state is %d", state);
for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
+ if (stream == AUDIO_STREAM_PATCH) {
+ continue;
+ }
handleIncallSonification((audio_stream_type_t)stream, true, true);
}
}
@@ -830,7 +836,6 @@ audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo)
{
-
routing_strategy strategy = getStrategy(stream);
audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
@@ -1587,6 +1592,11 @@ void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
}
mStreams[stream].mIndexMin = indexMin;
mStreams[stream].mIndexMax = indexMax;
+ //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
+ if (stream == AUDIO_STREAM_MUSIC) {
+ mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexMin = indexMin;
+ mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexMax = indexMax;
+ }
}
status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
@@ -1617,7 +1627,16 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
// update volume on all outputs whose current device is also selected by the same
// strategy as the device specified by the caller
audio_devices_t strategyDevice = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
- if ((device != AUDIO_DEVICE_OUT_DEFAULT) && (device & strategyDevice) == 0) {
+
+
+ //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
+ audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE;
+ if (stream == AUDIO_STREAM_MUSIC) {
+ mStreams[AUDIO_STREAM_ACCESSIBILITY].mIndexCur.add(device, index);
+ accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/);
+ }
+ if ((device != AUDIO_DEVICE_OUT_DEFAULT) &&
+ (device & (strategyDevice | accessibilityDevice)) == 0) {
return NO_ERROR;
}
status_t status = NO_ERROR;
@@ -1630,6 +1649,10 @@ status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
status = volStatus;
}
}
+ if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0)) {
+ status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY,
+ index, mOutputs.keyAt(i), curDevice);
+ }
}
return status;
}
@@ -3755,6 +3778,9 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
}
// Move tracks associated to this strategy from previous output to new output
for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
+ if (i == AUDIO_STREAM_PATCH) {
+ continue;
+ }
if (getStrategy((audio_stream_type_t)i) == strategy) {
mpClientInterface->invalidateStream((audio_stream_type_t)i);
}
@@ -3771,8 +3797,10 @@ void AudioPolicyManager::checkOutputForAllStrategies()
checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
checkOutputForStrategy(STRATEGY_SONIFICATION);
checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+ checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
checkOutputForStrategy(STRATEGY_MEDIA);
checkOutputForStrategy(STRATEGY_DTMF);
+ checkOutputForStrategy(STRATEGY_REROUTING);
}
audio_io_handle_t AudioPolicyManager::getA2dpOutput()
@@ -3861,11 +3889,13 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output,
// use device for strategy sonification
// 5: the strategy "respectful" sonification is active on the output:
// use device for strategy "respectful" sonification
- // 6: the strategy media is active on the output:
+ // 6: the strategy accessibility is active on the output:
+ // use device for strategy accessibility
+ // 7: the strategy media is active on the output:
// use device for strategy media
- // 7: the strategy DTMF is active on the output:
+ // 8: the strategy DTMF is active on the output:
// use device for strategy DTMF
- // 8: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
+ // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
// use device for strategy t-t-s
if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE) &&
mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
@@ -3879,12 +3909,16 @@ audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output,
device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
} else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {
device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
+ } else if (outputDesc->isStrategyActive(STRATEGY_ACCESSIBILITY)) {
+ device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
} else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {
device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
} else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {
device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
} else if (outputDesc->isStrategyActive(STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
+ } else if (outputDesc->isStrategyActive(STRATEGY_REROUTING)) {
+ device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
}
ALOGV("getNewOutputDevice() selected device %x", device);
@@ -3919,7 +3953,7 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre
// By checking the range of stream before calling getStrategy, we avoid
// getStrategy's behavior for invalid streams. getStrategy would do a ALOGE
// and then return STRATEGY_MEDIA, but we want to return the empty set.
- if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) {
+ if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
return AUDIO_DEVICE_NONE;
}
audio_devices_t devices;
@@ -3946,6 +3980,9 @@ audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stre
AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
audio_stream_type_t stream) {
+
+ ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
+
// stream to strategy mapping
switch (stream) {
case AUDIO_STREAM_VOICE_CALL:
@@ -3959,7 +3996,7 @@ AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
case AUDIO_STREAM_DTMF:
return STRATEGY_DTMF;
default:
- ALOGE("unknown stream type");
+ ALOGE("unknown stream type %d", stream);
case AUDIO_STREAM_SYSTEM:
// NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
// while key clicks are played produces a poor result
@@ -3969,6 +4006,10 @@ AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
return STRATEGY_ENFORCED_AUDIBLE;
case AUDIO_STREAM_TTS:
return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
+ case AUDIO_STREAM_ACCESSIBILITY:
+ return STRATEGY_ACCESSIBILITY;
+ case AUDIO_STREAM_REROUTING:
+ return STRATEGY_REROUTING;
}
}
@@ -4015,6 +4056,13 @@ uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr)
case AUDIO_USAGE_NOTIFICATION_EVENT:
return (uint32_t) STRATEGY_SONIFICATION_RESPECTFUL;
+ case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ if (isStreamActive(AUDIO_STREAM_RING, 0) ||
+ isStreamActive(AUDIO_STREAM_ALARM, 0)) {
+ return (uint32_t) STRATEGY_SONIFICATION;
+ }
+ return (uint32_t) STRATEGY_ACCESSIBILITY;
+
case AUDIO_USAGE_UNKNOWN:
default:
return (uint32_t) STRATEGY_MEDIA;
@@ -4282,6 +4330,9 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate
// The second device used for sonification is the same as the device used by media strategy
// FALL THROUGH
+ // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now
+ case STRATEGY_ACCESSIBILITY:
+ case STRATEGY_REROUTING:
case STRATEGY_MEDIA: {
uint32_t device2 = AUDIO_DEVICE_NONE;
if (strategy != STRATEGY_SONIFICATION) {
@@ -4933,6 +4984,7 @@ AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_
}
}
+/* static */
float AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
int indexInUi)
{
@@ -5056,6 +5108,11 @@ const AudioPolicyManager::VolumeCurvePoint
};
const AudioPolicyManager::VolumeCurvePoint
+ AudioPolicyManager::sFullScaleVolumeCurve[AudioPolicyManager::VOLCNT] = {
+ {0, 0.0f}, {1, 0.0f}, {2, 0.0f}, {100, 0.0f}
+};
+
+const AudioPolicyManager::VolumeCurvePoint
*AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT]
[AudioPolicyManager::DEVICE_CATEGORY_CNT] = {
{ // AUDIO_STREAM_VOICE_CALL
@@ -5119,6 +5176,24 @@ const AudioPolicyManager::VolumeCurvePoint
sSilentVolumeCurve, // DEVICE_CATEGORY_EARPIECE
sSilentVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
},
+ { // AUDIO_STREAM_ACCESSIBILITY
+ sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
+ sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+ sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+ sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
+ },
+ { // AUDIO_STREAM_REROUTING
+ sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
+ sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+ sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+ sFullScaleVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
+ },
+ { // AUDIO_STREAM_PATCH
+ sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
+ sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
+ sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
+ sFullScaleVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
+ },
};
void AudioPolicyManager::initializeVolumeCurves()
@@ -5142,6 +5217,8 @@ void AudioPolicyManager::initializeVolumeCurves()
sSpeakerSonificationVolumeCurveDrc;
mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
sSpeakerMediaVolumeCurveDrc;
+ mStreams[AUDIO_STREAM_ACCESSIBILITY].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
+ sSpeakerMediaVolumeCurveDrc;
}
}
@@ -5267,6 +5344,9 @@ void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);
for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
+ if (stream == AUDIO_STREAM_PATCH) {
+ continue;
+ }
checkAndSetVolume((audio_stream_type_t)stream,
mStreams[stream].getVolumeIndex(device),
output,
@@ -5284,6 +5364,9 @@ void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
{
ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
+ if (stream == AUDIO_STREAM_PATCH) {
+ continue;
+ }
if (getStrategy((audio_stream_type_t)stream) == strategy) {
setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);
}
@@ -5495,6 +5578,9 @@ bool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strateg
sysTime = systemTime();
}
for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
+ if (i == AUDIO_STREAM_PATCH) {
+ continue;
+ }
if (((getStrategy((audio_stream_type_t)i) == strategy) ||
(NUM_STRATEGIES == strategy)) &&
isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
@@ -7412,9 +7498,10 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_
switch (attr->usage) {
case AUDIO_USAGE_MEDIA:
case AUDIO_USAGE_GAME:
- case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
return AUDIO_STREAM_MUSIC;
+ case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
+ return AUDIO_STREAM_ACCESSIBILITY;
case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
return AUDIO_STREAM_SYSTEM;
case AUDIO_USAGE_VOICE_COMMUNICATION:
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 50d7831..7af6475 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -188,6 +188,8 @@ protected:
STRATEGY_DTMF,
STRATEGY_ENFORCED_AUDIBLE,
STRATEGY_TRANSMITTED_THROUGH_SPEAKER,
+ STRATEGY_ACCESSIBILITY,
+ STRATEGY_REROUTING,
NUM_STRATEGIES
};
@@ -437,6 +439,7 @@ protected:
static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT];
static const VolumeCurvePoint sLinearVolumeCurve[AudioPolicyManager::VOLCNT];
static const VolumeCurvePoint sSilentVolumeCurve[AudioPolicyManager::VOLCNT];
+ static const VolumeCurvePoint sFullScaleVolumeCurve[AudioPolicyManager::VOLCNT];
// default volume curves per stream and device category. See initializeVolumeCurves()
static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT];