summaryrefslogtreecommitdiffstats
path: root/services/audiopolicy
diff options
context:
space:
mode:
authorPaul McLean <pmclean@google.com>2015-04-17 13:15:36 -0600
committerPaul McLean <pmclean@google.com>2015-04-28 10:46:14 -0600
commit466dc8ed6ca6b7f585104806c48613dd34e608c9 (patch)
tree086bbd91d48e366377c02df8a65a5e2bad8675a6 /services/audiopolicy
parentdae24729d0b3ced8c4a7d7f9b631e852f564db4f (diff)
downloadframeworks_av-466dc8ed6ca6b7f585104806c48613dd34e608c9.zip
frameworks_av-466dc8ed6ca6b7f585104806c48613dd34e608c9.tar.gz
frameworks_av-466dc8ed6ca6b7f585104806c48613dd34e608c9.tar.bz2
Explicit routing in AudioRecord
Change-Id: I9cc5d54883a3e5c75d553fabb619fc8e49f4f9e5
Diffstat (limited to 'services/audiopolicy')
-rw-r--r--services/audiopolicy/AudioPolicyInterface.h1
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.cpp96
-rw-r--r--services/audiopolicy/managerdefault/AudioPolicyManager.h78
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp9
-rw-r--r--services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp5
-rw-r--r--services/audiopolicy/service/AudioPolicyService.h5
6 files changed, 139 insertions, 55 deletions
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 58c65fa..9230750 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -133,6 +133,7 @@ public:
audio_format_t format,
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
input_type_t *inputType) = 0;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index ba3fcaf..7de72de 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -689,7 +689,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
break;
}
}
- mOutputRoutes.addRoute(session, *stream, deviceDesc);
+ mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc);
return NO_ERROR;
}
@@ -1226,6 +1226,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
input_type_t *inputType)
{
ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
@@ -1247,6 +1248,16 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
}
halInputSource = inputSource;
+ // Explicit routing?
+ sp<DeviceDescriptor> deviceDesc;
+ for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
+ if (mAvailableInputDevices[i]->getId() == selectedDeviceId) {
+ deviceDesc = mAvailableInputDevices[i];
+ break;
+ }
+ }
+ mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc);
+
if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
@@ -1378,6 +1389,7 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
addInput(*input, inputDesc);
mpClientInterface->onAudioPortListUpdate();
+
return NO_ERROR;
}
@@ -1419,7 +1431,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
}
}
- if (inputDesc->mRefCount == 0) {
+ if (inputDesc->mRefCount == 0 || mInputRoutes.hasRouteChanged(session)) {
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
&& ((inputDesc->mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) {
@@ -1427,6 +1439,9 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input,
MIX_STATE_MIXING);
}
+ // Routing?
+ mInputRoutes.incRouteActivity(session);
+
if (mInputs.activeInputsCount() == 0) {
SoundTrigger::setCaptureState(true);
}
@@ -1479,6 +1494,10 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
}
inputDesc->mRefCount--;
+
+ // Routing?
+ mInputRoutes.decRouteActivity(session);
+
if (inputDesc->mRefCount == 0) {
// if input maps to a dynamic policy with an activity listener, notify of state change
if ((inputDesc->mPolicyMix != NULL)
@@ -1521,6 +1540,10 @@ void AudioPolicyManager::releaseInput(audio_io_handle_t input,
ALOGW("releaseInput() releasing unknown input %d", input);
return;
}
+
+ // Routing
+ mInputRoutes.removeRoute(session);
+
sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
ALOG_ASSERT(inputDesc != 0);
@@ -3771,7 +3794,6 @@ audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->mInputSource);
- ALOGV("getNewInputDevice() selected device %x", device);
return device;
}
@@ -4291,7 +4313,15 @@ audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t
audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
{
- return mEngine->getDeviceForInputSource(inputSource);
+ for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
+ sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
+ if (inputSource == route->mSource && route->mDeviceDescriptor != 0
+ /*&& route->mActivityCount != 0*/) {
+ return route->mDeviceDescriptor->type();
+ }
+ }
+
+ return mEngine->getDeviceForInputSource(inputSource);
}
float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
@@ -4514,8 +4544,8 @@ void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
// --- SessionRoute class implementation
void AudioPolicyManager::SessionRoute::log(const char* prefix) {
- ALOGI("%s[SessionRoute strm:0x%X, sess:0x%X, dev:0x%X refs:%d act:%d",
- prefix, mStreamType, mSession,
+ ALOGI("%s[SessionRoute strm:0x%X, src:%d, sess:0x%X, dev:0x%X refs:%d act:%d",
+ prefix, mStreamType, mSource, mSession,
mDeviceDescriptor != 0 ? mDeviceDescriptor->type() : AUDIO_DEVICE_NONE,
mRefCount, mActivityCount);
}
@@ -4537,28 +4567,6 @@ bool AudioPolicyManager::SessionRouteMap::hasRouteChanged(audio_session_t sessio
return false;
}
-void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session,
- audio_stream_type_t streamType,
- sp<DeviceDescriptor> deviceDescriptor)
-{
- sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
- if (route != NULL) {
- if ((route->mDeviceDescriptor == 0 && deviceDescriptor != 0) ||
- (!route->mDeviceDescriptor->equals(deviceDescriptor))) {
- route->mChanged = true;
- }
- route->mRefCount++;
- route->mDeviceDescriptor = deviceDescriptor;
- } else {
- route = new AudioPolicyManager::SessionRoute(session, streamType, deviceDescriptor);
- route->mRefCount++;
- add(session, route);
- if (deviceDescriptor != 0) {
- route->mChanged = true;
- }
- }
-}
-
void AudioPolicyManager::SessionRouteMap::removeRoute(audio_session_t session)
{
sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
@@ -4594,6 +4602,38 @@ void AudioPolicyManager::SessionRouteMap::log(const char* caption) {
}
}
+void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session,
+ audio_stream_type_t streamType,
+ audio_source_t source,
+ sp<DeviceDescriptor> descriptor)
+{
+ if (mMapType == MAPTYPE_INPUT && streamType != SessionRoute::STREAM_TYPE_NA) {
+ ALOGE("Adding Output Route to InputRouteMap");
+ return;
+ } else if (mMapType == MAPTYPE_OUTPUT && source != SessionRoute::SOURCE_TYPE_NA) {
+ ALOGE("Adding Input Route to OutputRouteMap");
+ return;
+ }
+
+ sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
+
+ if (route != 0) {
+ if ((route->mDeviceDescriptor == 0 && descriptor != 0) ||
+ (!route->mDeviceDescriptor->equals(descriptor))) {
+ route->mChanged = true;
+ }
+ route->mRefCount++;
+ route->mDeviceDescriptor = descriptor;
+ } else {
+ route = new AudioPolicyManager::SessionRoute(session, streamType, source, descriptor);
+ route->mRefCount++;
+ add(session, route);
+ if (descriptor != 0) {
+ route->mChanged = true;
+ }
+ }
+}
+
void AudioPolicyManager::defaultAudioPolicyConfig(void)
{
sp<HwModule> module;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 521f6c4..b965411 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -131,6 +131,7 @@ public:
audio_format_t format,
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId,
input_type_t *inputType);
// indicates to the audio policy manager that the input starts being used.
@@ -233,45 +234,84 @@ public:
routing_strategy getStrategy(audio_stream_type_t stream) const;
protected:
- class SessionRoute : public RefBase
- {
+ class SessionRoute : public RefBase {
public:
- friend class SessionRouteMap;
+ // For Input (Source) routes, use STREAM_TYPE_NA ("NA" = "not applicable)for the
+ // streamType argument
+ static const audio_stream_type_t STREAM_TYPE_NA = AUDIO_STREAM_DEFAULT;
+
+ // For Output (Sink) routes, use SOURCE_TYPE_NA ("NA" = "not applicable") for the
+ // source argument
+
+ static const audio_source_t SOURCE_TYPE_NA = AUDIO_SOURCE_DEFAULT;
+
SessionRoute(audio_session_t session,
audio_stream_type_t streamType,
+ audio_source_t source,
sp<DeviceDescriptor> deviceDescriptor)
- : mSession(session),
- mStreamType(streamType),
- mDeviceDescriptor(deviceDescriptor),
- mRefCount(0),
- mActivityCount(0),
- mChanged(false) {}
-
- void log(const char* prefix);
+ : mSession(session),
+ mDeviceDescriptor(deviceDescriptor),
+ mRefCount(0),
+ mActivityCount(0),
+ mChanged(false),
+ mStreamType(streamType),
+ mSource(source) {}
audio_session_t mSession;
- audio_stream_type_t mStreamType;
sp<DeviceDescriptor> mDeviceDescriptor;
+ void log(const char* prefix);
+
// "reference" counting
int mRefCount; // +/- on references
int mActivityCount; // +/- on start/stop
bool mChanged;
+
+ // for outputs
+ const audio_stream_type_t mStreamType;
+
+ // for inputs
+ const audio_source_t mSource;
};
- class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>>
- {
- public:
+ class SessionRouteMap: public KeyedVector<audio_session_t, sp<SessionRoute>> {
+ public:
+ // These constants identify the SessionRoutMap as holding EITHER input routes,
+ // or output routes. An error will occur if an attempt is made to add a SessionRoute
+ // object with mStreamType == STREAM_TYPE_NA (i.e. an input SessionRoute) to a
+ // SessionRoutMap that is marked for output (i.e. mMapType == SESSION_ROUTE_MAP_OUTPUT)
+ // and similarly for output SessionRoutes and Input SessionRouteMaps.
+ typedef enum {
+ MAPTYPE_INPUT = 0,
+ MAPTYPE_OUTPUT = 1
+ } session_route_map_type_t;
+
+ SessionRouteMap(session_route_map_type_t mapType) :
+ mMapType(mapType) {
+ }
+
bool hasRoute(audio_session_t session);
- void addRoute(audio_session_t session, audio_stream_type_t streamType,
- sp<DeviceDescriptor> deviceDescriptor);
void removeRoute(audio_session_t session);
int incRouteActivity(audio_session_t session);
int decRouteActivity(audio_session_t session);
bool hasRouteChanged(audio_session_t session); // also clears the changed flag
void log(const char* caption);
+
+ // Specify an Output(Sink) route by passing SessionRoute::SOURCE_TYPE_NA in the
+ // source argument.
+ // Specify an Input(Source) rout by passing SessionRoute::AUDIO_STREAM_DEFAULT
+ // in the streamType argument.
+ void addRoute(audio_session_t session,
+ audio_stream_type_t streamType,
+ audio_source_t source,
+ sp<DeviceDescriptor> deviceDescriptor);
+
+ private:
+ // Used to mark a SessionRoute as for either inputs (mMapType == kSessionRouteMap_Input)
+ // or outputs (mMapType == kSessionRouteMap_Output)
+ const session_route_map_type_t mMapType;
};
// From AudioPolicyManagerObserver
@@ -535,8 +575,8 @@ protected:
DeviceVector mAvailableOutputDevices; // all available output devices
DeviceVector mAvailableInputDevices; // all available input devices
- SessionRouteMap mOutputRoutes;
- SessionRouteMap mInputRoutes;
+ SessionRouteMap mOutputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_OUTPUT);
+ SessionRouteMap mInputRoutes = SessionRouteMap(SessionRouteMap::MAPTYPE_INPUT);
StreamDescriptorCollection mStreams; // stream descriptors for volume control
bool mLimitRingtoneVolume; // limit ringtone volume to music volume if headset connected
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index e764eda..5ceb1cf 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -150,7 +150,7 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
- int mSelectedDeviceId,
+ audio_port_handle_t selectedDeviceId,
const audio_offload_info_t *offloadInfo)
{
if (mAudioPolicyManager == NULL) {
@@ -159,7 +159,7 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
ALOGV("getOutput()");
Mutex::Autolock _l(mLock);
return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, samplingRate,
- format, channelMask, flags, mSelectedDeviceId, offloadInfo);
+ format, channelMask, flags, selectedDeviceId, offloadInfo);
}
status_t AudioPolicyService::startOutput(audio_io_handle_t output,
@@ -251,7 +251,8 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags)
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@@ -273,7 +274,7 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
// the audio_in_acoustics_t parameter is ignored by get_input()
status = mAudioPolicyManager->getInputForAttr(attr, input, session,
samplingRate, format, channelMask,
- flags, &inputType);
+ flags, selectedDeviceId, &inputType);
audioPolicyEffects = mAudioPolicyEffects;
if (status == NO_ERROR) {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index f783437..433e712 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -237,7 +237,8 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags __unused)
+ audio_input_flags_t flags __unused,
+ audio_port_handle_t selectedDeviceId __unused)
{
if (mpAudioPolicy == NULL) {
return NO_INIT;
@@ -568,7 +569,7 @@ status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
audio_format_t format,
audio_channel_mask_t channelMask,
audio_output_flags_t flags,
- int selectedDeviceId __unused,
+ audio_port_handle_t selectedDeviceId __unused,
const audio_offload_info_t *offloadInfo)
{
if (attr != NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 4e25d33..07ea96b 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -84,7 +84,7 @@ public:
audio_format_t format = AUDIO_FORMAT_DEFAULT,
audio_channel_mask_t channelMask = 0,
audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
- int selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE,
const audio_offload_info_t *offloadInfo = NULL);
virtual status_t startOutput(audio_io_handle_t output,
audio_stream_type_t stream,
@@ -101,7 +101,8 @@ public:
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_input_flags_t flags);
+ audio_input_flags_t flags,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
virtual status_t startInput(audio_io_handle_t input,
audio_session_t session);
virtual status_t stopInput(audio_io_handle_t input,