Revert "audio policy for concurrent capture."
This reverts commit 4b2fcd8abf90b1bd95539f9f4ef2ac39ce9e2df1.
Bug:26841909
Change-Id: Ifc74b195394b9fb3f73d33455ad061bd896d5331
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 75e0530..dd3f144 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -67,14 +67,6 @@
API_INPUT_TELEPHONY_RX, // used for capture from telephony RX path
} input_type_t;
- enum {
- API_INPUT_CONCURRENCY_NONE = 0,
- API_INPUT_CONCURRENCY_CALL = (1 << 0), // Concurrency with a call
- API_INPUT_CONCURRENCY_CAPTURE = (1 << 1), // Concurrency with another capture
- };
-
- typedef uint32_t concurrency_type__mask_t;
-
public:
virtual ~AudioPolicyInterface() {}
//
@@ -148,8 +140,7 @@
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,
- audio_session_t session,
- concurrency_type__mask_t *concurrency) = 0;
+ audio_session_t session) = 0;
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input,
audio_session_t session) = 0;
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index e3ee4e5..34984f9 100755
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -30,9 +30,9 @@
/**
* A device mask for all audio input devices that are considered "virtual" when evaluating
- * active inputs in getActiveInputs()
+ * active inputs in getActiveInput()
*/
-#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX)
+#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_FM_TUNER)
/**
@@ -88,41 +88,3 @@
(((device & AUDIO_DEVICE_BIT_IN) == 0) &&
((device & APM_AUDIO_DEVICE_OUT_MATCH_ADDRESS_ALL) != 0));
}
-
-/**
- * Returns the priority of a given audio source for capture. The priority is used when more than one
- * capture session is active on a given input stream to determine which session drives routing and
- * effect configuration.
- *
- * @param[in] inputSource to consider. Valid sources are:
- * - AUDIO_SOURCE_VOICE_COMMUNICATION
- * - AUDIO_SOURCE_CAMCORDER
- * - AUDIO_SOURCE_MIC
- * - AUDIO_SOURCE_FM_TUNER
- * - AUDIO_SOURCE_VOICE_RECOGNITION
- * - AUDIO_SOURCE_HOTWORD
- *
- * @return the corresponding input source priority or 0 if priority is irrelevant for this source.
- * This happens when the specified source cannot share a given input stream (e.g remote submix)
- * The higher the value, the higher the priority.
- */
-static inline int32_t source_priority(audio_source_t inputSource)
-{
- switch (inputSource) {
- case AUDIO_SOURCE_VOICE_COMMUNICATION:
- return 6;
- case AUDIO_SOURCE_CAMCORDER:
- return 5;
- case AUDIO_SOURCE_MIC:
- return 4;
- case AUDIO_SOURCE_FM_TUNER:
- return 3;
- case AUDIO_SOURCE_VOICE_RECOGNITION:
- return 2;
- case AUDIO_SOURCE_HOTWORD:
- return 1;
- default:
- break;
- }
- return 0;
-}
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 049079e..77c0d07 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -63,8 +63,7 @@
const sp<AudioSession>& audioSession);
status_t removeAudioSession(audio_session_t session);
sp<AudioSession> getAudioSession(audio_session_t session) const;
- AudioSessionCollection getAudioSessions(bool activeOnly) const;
- audio_source_t getHighestPrioritySource(bool activeOnly) const;
+ AudioSessionCollection getActiveAudioSessions() const;
private:
audio_port_handle_t mId;
@@ -94,7 +93,7 @@
* Only considers inputs from physical devices (e.g. main mic, headset mic) when
* ignoreVirtualInputs is true.
*/
- Vector<sp <AudioInputDescriptor> > getActiveInputs(bool ignoreVirtualInputs = true);
+ audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true);
audio_devices_t getSupportedDevices(audio_io_handle_t handle) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index 0da3aea..34149bd 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -159,10 +159,6 @@
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const = 0;
virtual sp<AudioPort> getAudioPort() const = 0;
- virtual bool hasSameHwModuleAs(const sp<AudioPortConfig>& other) const {
- return (other != 0) &&
- (other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle());
- }
uint32_t mSamplingRate;
audio_format_t mFormat;
audio_channel_mask_t mChannelMask;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index 87c4c9a..576822c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -87,7 +87,6 @@
AudioSessionCollection getActiveSessions() const;
bool hasActiveSession() const;
bool isSourceActive(audio_source_t source) const;
- audio_source_t getHighestPrioritySource(bool activeOnly) const;
status_t dump(int fd, int spaces) const;
};
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 6281715..9b6469c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -132,12 +132,6 @@
return mSessions.isSourceActive(source);
}
-audio_source_t AudioInputDescriptor::getHighestPrioritySource(bool activeOnly) const
-{
-
- return mSessions.getHighestPrioritySource(activeOnly);
-}
-
bool AudioInputDescriptor::isSoundTrigger() const {
// sound trigger and non sound trigger sessions are not mixed
// on a given input
@@ -149,13 +143,9 @@
return mSessions.valueFor(session);
}
-AudioSessionCollection AudioInputDescriptor::getAudioSessions(bool activeOnly) const
+AudioSessionCollection AudioInputDescriptor::getActiveAudioSessions() const
{
- if (activeOnly) {
- return mSessions.getActiveSessions();
- } else {
- return mSessions;
- }
+ return mSessions.getActiveSessions();
}
status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
@@ -226,19 +216,17 @@
return count;
}
-Vector<sp <AudioInputDescriptor> > AudioInputCollection::getActiveInputs(bool ignoreVirtualInputs)
+audio_io_handle_t AudioInputCollection::getActiveInput(bool ignoreVirtualInputs)
{
- Vector<sp <AudioInputDescriptor> > activeInputs;
-
for (size_t i = 0; i < size(); i++) {
const sp<AudioInputDescriptor> inputDescriptor = valueAt(i);
if ((inputDescriptor->isActive())
&& (!ignoreVirtualInputs ||
!is_virtual_input_device(inputDescriptor->mDevice))) {
- activeInputs.add(inputDescriptor);
+ return keyAt(i);
}
}
- return activeInputs;
+ return 0;
}
audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index f5927ab..5d0f03f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -81,7 +81,7 @@
return sharesHwModuleWith(outputDesc->subOutput1()) ||
sharesHwModuleWith(outputDesc->subOutput2());
} else {
- return hasSameHwModuleAs(outputDesc);
+ return (getModuleHandle() == outputDesc->getModuleHandle());
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index a08ce02..597c029 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -18,7 +18,6 @@
//#define LOG_NDEBUG 0
#include <AudioPolicyInterface.h>
-#include "policy.h"
#include "AudioSession.h"
#include "AudioGain.h"
#include "TypeConverter.h"
@@ -208,24 +207,6 @@
return false;
}
-audio_source_t AudioSessionCollection::getHighestPrioritySource(bool activeOnly) const
-{
- audio_source_t source = AUDIO_SOURCE_DEFAULT;
- int32_t priority = -1;
-
- for (size_t i = 0; i < size(); i++) {
- const sp<AudioSession> audioSession = valueAt(i);
- if (activeOnly && audioSession->activeCount() == 0) {
- continue;
- }
- int32_t curPriority = source_priority(audioSession->inputSource());
- if (curPriority > priority) {
- priority = curPriority;
- source = audioSession->inputSource();
- }
- }
- return source;
-}
status_t AudioSessionCollection::dump(int fd, int spaces) const
{
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 74ff992..3c70ce8 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -420,17 +420,15 @@
// FIXME: would be better to refine to only inputs whose profile connects to the
// call TX device but this information is not in the audio patch and logic here must be
// symmetric to the one in startInput()
- Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
- if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
- AudioSessionCollection activeSessions =
- activeDesc->getAudioSessions(true /*activeOnly*/);
- for (size_t j = 0; j < activeSessions.size(); j++) {
- audio_session_t activeSession = activeSessions.keyAt(j);
- stopInput(activeDesc->mIoHandle, activeSession);
- releaseInput(activeDesc->mIoHandle, activeSession);
- }
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0) {
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ if (activeDesc->getModuleHandle() == txSourceDeviceDesc->getModuleHandle()) {
+ //FIXME: consider all active sessions
+ AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
+ audio_session_t activeSession = activeSessions.keyAt(0);
+ stopInput(activeInput, activeSession);
+ releaseInput(activeInput, activeSession);
}
}
@@ -596,16 +594,15 @@
}
}
- Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeDesc = activeInputs[i];
- audio_devices_t newDevice = getNewInputDevice(activeDesc);
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0) {
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ audio_devices_t newDevice = getNewInputDevice(activeInput);
// Force new input selection if the new device can not be reached via current input
- if (activeDesc->mProfile->getSupportedDevices().types() &
- (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
- setInputDevice(activeDesc->mIoHandle, newDevice);
+ if (activeDesc->mProfile->getSupportedDevices().types() & (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
+ setInputDevice(activeInput, newDevice);
} else {
- closeInput(activeDesc->mIoHandle);
+ closeInput(activeInput);
}
}
}
@@ -1337,7 +1334,6 @@
*input = AUDIO_IO_HANDLE_NONE;
*inputType = API_INPUT_INVALID;
-
audio_devices_t device;
// handle legacy remote submix case where the address was not always specified
String8 address = String8("");
@@ -1475,22 +1471,14 @@
isSoundTrigger,
policyMix, mpClientInterface);
-
+// TODO enable input reuse
+#if 0
// reuse an open input if possible
for (size_t i = 0; i < mInputs.size(); i++) {
sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
- // reuse input if:
- // - it shares the same profile
- // AND
- // - it is not a reroute submix input
- // AND
- // - it is: not used for sound trigger
- // OR
- // used for sound trigger and all clients use the same session ID
- //
- if ((profile == desc->mProfile) &&
- (isSoundTrigger == desc->isSoundTrigger()) &&
- !is_virtual_input_device(device)) {
+ // reuse input if it shares the same profile and same sound trigger attribute
+ if (profile == desc->mProfile &&
+ isSoundTrigger == desc->isSoundTrigger()) {
sp<AudioSession> as = desc->getAudioSession(session);
if (as != 0) {
@@ -1500,33 +1488,16 @@
} else {
ALOGW("getInputForDevice() record with different attributes"
" exists for session %d", session);
- break;
+ return input;
}
- } else if (isSoundTrigger) {
- break;
- }
- // force close input if current source is now the highest priority request on this input
- // and current input properties are not exactly as requested.
- if ((desc->mSamplingRate != samplingRate ||
- desc->mChannelMask != channelMask ||
- desc->mFormat != format) &&
- (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
- source_priority(inputSource))) {
- ALOGV("%s: ", __FUNCTION__);
- AudioSessionCollection sessions = desc->getAudioSessions(false /*activeOnly*/);
- for (size_t j = 0; j < sessions.size(); j++) {
- audio_session_t currentSession = sessions.keyAt(j);
- stopInput(desc->mIoHandle, currentSession);
- releaseInput(desc->mIoHandle, currentSession);
- }
- break;
} else {
desc->addAudioSession(session, audioSession);
- ALOGV("%s: reusing input %d", __FUNCTION__, mInputs.keyAt(i));
- return mInputs.keyAt(i);
}
+ ALOGV("getInputForDevice() reusing input %d", mInputs.keyAt(i));
+ return mInputs.keyAt(i);
}
}
+#endif
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = profileSamplingRate;
@@ -1569,50 +1540,10 @@
return input;
}
-bool AudioPolicyManager::isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
- const sp<AudioSession>& audioSession)
-{
- // Do not allow capture if an active voice call is using a software patch and
- // the call TX source device is on the same HW module.
- // FIXME: would be better to refine to only inputs whose profile connects to the
- // call TX device but this information is not in the audio patch
- if (mCallTxPatch != 0 &&
- inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
- return false;
- }
-
- // starting concurrent capture is enabled if:
- // 1) capturing for re-routing
- // 2) capturing for HOTWORD source
- // 3) capturing for FM TUNER source
- // 3) All other active captures are either for re-routing or HOTWORD
-
- if (is_virtual_input_device(inputDesc->mDevice) ||
- audioSession->inputSource() == AUDIO_SOURCE_HOTWORD ||
- audioSession->inputSource() == AUDIO_SOURCE_FM_TUNER) {
- return true;
- }
-
- Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
- for (size_t i = 0; i < activeInputs.size(); i++) {
- sp<AudioInputDescriptor> activeInput = activeInputs[i];
- if ((activeInput->inputSource() != AUDIO_SOURCE_HOTWORD) &&
- (activeInput->inputSource() != AUDIO_SOURCE_FM_TUNER) &&
- !is_virtual_input_device(activeInput->mDevice)) {
- return false;
- }
- }
-
- return true;
-}
-
-
status_t AudioPolicyManager::startInput(audio_io_handle_t input,
- audio_session_t session,
- concurrency_type__mask_t *concurrency)
+ audio_session_t session)
{
ALOGV("startInput() input %d", input);
- *concurrency = API_INPUT_CONCURRENCY_NONE;
ssize_t index = mInputs.indexOfKey(input);
if (index < 0) {
ALOGW("startInput() unknown input %d", input);
@@ -1626,52 +1557,74 @@
return BAD_VALUE;
}
- if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
- ALOGW("startInput(%d) failed: other input already started", input);
- return INVALID_OPERATION;
- }
+ // virtual input devices are compatible with other input devices
+ if (!is_virtual_input_device(inputDesc->mDevice)) {
- if (isInCall()) {
- *concurrency |= API_INPUT_CONCURRENCY_CALL;
- }
- if (mInputs.activeInputsCount() != 0) {
- *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
+ // for a non-virtual input device, check if there is another (non-virtual) active input
+ audio_io_handle_t activeInput = mInputs.getActiveInput();
+ if (activeInput != 0 && activeInput != input) {
+
+ // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
+ // otherwise the active input continues and the new input cannot be started.
+ sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
+ if ((activeDesc->inputSource() == AUDIO_SOURCE_HOTWORD) &&
+ !activeDesc->hasPreemptedSession(session)) {
+ ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
+ //FIXME: consider all active sessions
+ AudioSessionCollection activeSessions = activeDesc->getActiveAudioSessions();
+ audio_session_t activeSession = activeSessions.keyAt(0);
+ SortedVector<audio_session_t> sessions =
+ activeDesc->getPreemptedSessions();
+ sessions.add(activeSession);
+ inputDesc->setPreemptedSessions(sessions);
+ stopInput(activeInput, activeSession);
+ releaseInput(activeInput, activeSession);
+ } else {
+ ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
+ return INVALID_OPERATION;
+ }
+ }
+
+ // Do not allow capture if an active voice call is using a software patch and
+ // the call TX source device is on the same HW module.
+ // FIXME: would be better to refine to only inputs whose profile connects to the
+ // call TX device but this information is not in the audio patch
+ if (mCallTxPatch != 0 &&
+ inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
+ return INVALID_OPERATION;
+ }
}
// Routing?
mInputRoutes.incRouteActivity(session);
- if (audioSession->activeCount() == 0 || mInputRoutes.hasRouteChanged(session)) {
+ if (!inputDesc->isActive() || mInputRoutes.hasRouteChanged(session)) {
+ // if input maps to a dynamic policy with an activity listener, notify of state change
+ if ((inputDesc->mPolicyMix != NULL)
+ && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+ mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
+ MIX_STATE_MIXING);
+ }
- setInputDevice(input, getNewInputDevice(inputDesc), true /* force */);
+ if (mInputs.activeInputsCount() == 0) {
+ SoundTrigger::setCaptureState(true);
+ }
+ setInputDevice(input, getNewInputDevice(input), true /* force */);
- if (!inputDesc->isActive()) {
- // if input maps to a dynamic policy with an activity listener, notify of state change
- if ((inputDesc->mPolicyMix != NULL)
- && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
- mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
- MIX_STATE_MIXING);
+ // automatically enable the remote submix output when input is started if not
+ // used by a policy mix of type MIX_TYPE_RECORDERS
+ // For remote submix (a virtual device), we open only one input per capture request.
+ if (audio_is_remote_submix_device(inputDesc->mDevice)) {
+ String8 address = String8("");
+ if (inputDesc->mPolicyMix == NULL) {
+ address = String8("0");
+ } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
+ address = inputDesc->mPolicyMix->mRegistrationId;
}
-
- if (mInputs.activeInputsCount() == 0) {
- SoundTrigger::setCaptureState(true);
- }
-
- // automatically enable the remote submix output when input is started if not
- // used by a policy mix of type MIX_TYPE_RECORDERS
- // For remote submix (a virtual device), we open only one input per capture request.
- if (audio_is_remote_submix_device(inputDesc->mDevice)) {
- String8 address = String8("");
- if (inputDesc->mPolicyMix == NULL) {
- address = String8("0");
- } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
- address = inputDesc->mPolicyMix->mRegistrationId;
- }
- if (address != "") {
- setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- address, "remote-submix");
- }
+ if (address != "") {
+ setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+ AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ address, "remote-submix");
}
}
}
@@ -1709,41 +1662,36 @@
// Routing?
mInputRoutes.decRouteActivity(session);
- if (audioSession->activeCount() == 0) {
-
- if (inputDesc->isActive()) {
- setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
- } else {
- // if input maps to a dynamic policy with an activity listener, notify of state change
- if ((inputDesc->mPolicyMix != NULL)
- && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
- mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
- MIX_STATE_IDLE);
- }
-
- // automatically disable the remote submix output when input is stopped if not
- // used by a policy mix of type MIX_TYPE_RECORDERS
- if (audio_is_remote_submix_device(inputDesc->mDevice)) {
- String8 address = String8("");
- if (inputDesc->mPolicyMix == NULL) {
- address = String8("0");
- } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
- address = inputDesc->mPolicyMix->mRegistrationId;
- }
- if (address != "") {
- setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
- AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- address, "remote-submix");
- }
- }
-
- resetInputDevice(input);
-
- if (mInputs.activeInputsCount() == 0) {
- SoundTrigger::setCaptureState(false);
- }
- inputDesc->clearPreemptedSessions();
+ if (!inputDesc->isActive()) {
+ // if input maps to a dynamic policy with an activity listener, notify of state change
+ if ((inputDesc->mPolicyMix != NULL)
+ && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
+ mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
+ MIX_STATE_IDLE);
}
+
+ // automatically disable the remote submix output when input is stopped if not
+ // used by a policy mix of type MIX_TYPE_RECORDERS
+ if (audio_is_remote_submix_device(inputDesc->mDevice)) {
+ String8 address = String8("");
+ if (inputDesc->mPolicyMix == NULL) {
+ address = String8("0");
+ } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
+ address = inputDesc->mPolicyMix->mRegistrationId;
+ }
+ if (address != "") {
+ setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+ AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ address, "remote-submix");
+ }
+ }
+
+ resetInputDevice(input);
+
+ if (mInputs.activeInputsCount() == 0) {
+ SoundTrigger::setCaptureState(false);
+ }
+ inputDesc->clearPreemptedSessions();
}
return NO_ERROR;
}
@@ -2505,7 +2453,7 @@
// create a software bridge in PatchPanel if:
// - source and sink devices are on differnt HW modules OR
// - audio HAL version is < 3.0
- if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
+ if ((srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) ||
(srcDeviceDesc->mModule->getHalVersion() < AUDIO_DEVICE_API_VERSION_3_0)) {
// support only one sink device for now to simplify output selection logic
if (patch->num_sinks > 1) {
@@ -2605,7 +2553,7 @@
return BAD_VALUE;
}
setInputDevice(inputDesc->mIoHandle,
- getNewInputDevice(inputDesc),
+ getNewInputDevice(inputDesc->mIoHandle),
true,
NULL);
} else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
@@ -4231,9 +4179,9 @@
return device;
}
-audio_devices_t AudioPolicyManager::getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc)
+audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
{
- audio_devices_t device = AUDIO_DEVICE_NONE;
+ sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
if (index >= 0) {
@@ -4245,12 +4193,7 @@
}
}
- audio_source_t source = inputDesc->getHighestPrioritySource(true /*activeOnly*/);
- if (isInCall()) {
- device = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
- } else if (source != AUDIO_SOURCE_DEFAULT) {
- device = getDeviceAndMixForInputSource(source);
- }
+ audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->inputSource());
return device;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index a9f597f..18d03b0 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -139,8 +139,7 @@
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input,
- audio_session_t session,
- concurrency_type__mask_t *concurrency);
+ audio_session_t session);
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input,
@@ -410,7 +409,7 @@
void updateDevicesAndOutputs();
// selects the most appropriate device on input for current state
- audio_devices_t getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc);
+ audio_devices_t getNewInputDevice(audio_io_handle_t input);
virtual uint32_t getMaxEffectsCpuLoad()
{
@@ -510,8 +509,6 @@
void clearAudioSources(uid_t uid);
- bool isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
- const sp<AudioSession>& audioSession);
uid_t mUidCached;
AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp
index eed545e..f6f8276 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.cpp
+++ b/services/audiopolicy/service/AudioPolicyEffects.cpp
@@ -57,11 +57,11 @@
}
mInputSources.clear();
- for (i = 0; i < mInputSessions.size(); i++) {
- mInputSessions.valueAt(i)->mEffects.clear();
- delete mInputSessions.valueAt(i);
+ for (i = 0; i < mInputs.size(); i++) {
+ mInputs.valueAt(i)->mEffects.clear();
+ delete mInputs.valueAt(i);
}
- mInputSessions.clear();
+ mInputs.clear();
// release audio output processing resources
for (i = 0; i < mOutputStreams.size(); i++) {
@@ -79,7 +79,7 @@
status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
audio_source_t inputSource,
- audio_session_t audioSession)
+ int audioSession)
{
status_t status = NO_ERROR;
@@ -93,19 +93,19 @@
ALOGV("addInputEffects(): no processing needs to be attached to this source");
return status;
}
- ssize_t idx = mInputSessions.indexOfKey(audioSession);
- EffectVector *sessionDesc;
+ ssize_t idx = mInputs.indexOfKey(input);
+ EffectVector *inputDesc;
if (idx < 0) {
- sessionDesc = new EffectVector(audioSession);
- mInputSessions.add(audioSession, sessionDesc);
+ inputDesc = new EffectVector(audioSession);
+ mInputs.add(input, inputDesc);
} else {
// EffectVector is existing and we just need to increase ref count
- sessionDesc = mInputSessions.valueAt(idx);
+ inputDesc = mInputs.valueAt(idx);
}
- sessionDesc->mRefCount++;
+ inputDesc->mRefCount++;
- ALOGV("addInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
- if (sessionDesc->mRefCount == 1) {
+ ALOGV("addInputEffects(): input: %d, refCount: %d", input, inputDesc->mRefCount);
+ if (inputDesc->mRefCount == 1) {
Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
EffectDesc *effect = effects[i];
@@ -123,37 +123,36 @@
}
ALOGV("addInputEffects(): added Fx %s on source: %d",
effect->mName, (int32_t)aliasSource);
- sessionDesc->mEffects.add(fx);
+ inputDesc->mEffects.add(fx);
}
- sessionDesc->setProcessorEnabled(true);
+ inputDesc->setProcessorEnabled(true);
}
return status;
}
-status_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input,
- audio_session_t audioSession)
+status_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input)
{
status_t status = NO_ERROR;
Mutex::Autolock _l(mLock);
- ssize_t index = mInputSessions.indexOfKey(audioSession);
+ ssize_t index = mInputs.indexOfKey(input);
if (index < 0) {
return status;
}
- EffectVector *sessionDesc = mInputSessions.valueAt(index);
- sessionDesc->mRefCount--;
- ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
- if (sessionDesc->mRefCount == 0) {
- sessionDesc->setProcessorEnabled(false);
- delete sessionDesc;
- mInputSessions.removeItemsAt(index);
+ EffectVector *inputDesc = mInputs.valueAt(index);
+ inputDesc->mRefCount--;
+ ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, inputDesc->mRefCount);
+ if (inputDesc->mRefCount == 0) {
+ inputDesc->setProcessorEnabled(false);
+ delete inputDesc;
+ mInputs.removeItemsAt(index);
ALOGV("releaseInputEffects(): all effects released");
}
return status;
}
-status_t AudioPolicyEffects::queryDefaultInputEffects(audio_session_t audioSession,
+status_t AudioPolicyEffects::queryDefaultInputEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count)
{
@@ -161,16 +160,16 @@
Mutex::Autolock _l(mLock);
size_t index;
- for (index = 0; index < mInputSessions.size(); index++) {
- if (mInputSessions.valueAt(index)->mSessionId == audioSession) {
+ for (index = 0; index < mInputs.size(); index++) {
+ if (mInputs.valueAt(index)->mSessionId == audioSession) {
break;
}
}
- if (index == mInputSessions.size()) {
+ if (index == mInputs.size()) {
*count = 0;
return BAD_VALUE;
}
- Vector< sp<AudioEffect> > effects = mInputSessions.valueAt(index)->mEffects;
+ Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
for (size_t i = 0; i < effects.size(); i++) {
effect_descriptor_t desc = effects[i]->descriptor();
@@ -186,7 +185,7 @@
}
-status_t AudioPolicyEffects::queryDefaultOutputSessionEffects(audio_session_t audioSession,
+status_t AudioPolicyEffects::queryDefaultOutputSessionEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count)
{
@@ -221,7 +220,7 @@
status_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession)
+ int audioSession)
{
status_t status = NO_ERROR;
@@ -276,7 +275,7 @@
status_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession)
+ int audioSession)
{
status_t status = NO_ERROR;
(void) output; // argument not used for now
diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h
index 58ea24c..3dec437 100644
--- a/services/audiopolicy/service/AudioPolicyEffects.h
+++ b/services/audiopolicy/service/AudioPolicyEffects.h
@@ -51,7 +51,7 @@
// Return a list of effect descriptors for default input effects
// associated with audioSession
- status_t queryDefaultInputEffects(audio_session_t audioSession,
+ status_t queryDefaultInputEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count);
@@ -59,16 +59,15 @@
// Effects are attached depending on the audio_source_t
status_t addInputEffects(audio_io_handle_t input,
audio_source_t inputSource,
- audio_session_t audioSession);
+ int audioSession);
// Add all input effects associated to this input
- status_t releaseInputEffects(audio_io_handle_t input,
- audio_session_t audioSession);
+ status_t releaseInputEffects(audio_io_handle_t input);
// Return a list of effect descriptors for default output effects
// associated with audioSession
- status_t queryDefaultOutputSessionEffects(audio_session_t audioSession,
+ status_t queryDefaultOutputSessionEffects(int audioSession,
effect_descriptor_t *descriptors,
uint32_t *count);
@@ -76,12 +75,12 @@
// Effects are attached depending on the audio_stream_type_t
status_t addOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession);
+ int audioSession);
// release all output effects associated with this output stream and audiosession
status_t releaseOutputSessionEffects(audio_io_handle_t output,
audio_stream_type_t stream,
- audio_session_t audioSession);
+ int audioSession);
private:
@@ -179,17 +178,17 @@
size_t *curSize,
size_t *totSize);
- // protects access to mInputSources, mInputSessions, mOutputStreams, mOutputSessions
+ // protects access to mInputSources, mInputs, mOutputStreams, mOutputSessions
Mutex mLock;
// Automatic input effects are configured per audio_source_t
KeyedVector< audio_source_t, EffectDescVector* > mInputSources;
// Automatic input effects are unique for audio_io_handle_t
- KeyedVector< audio_session_t, EffectVector* > mInputSessions;
+ KeyedVector< audio_io_handle_t, EffectVector* > mInputs;
// Automatic output effects are organized per audio_stream_type_t
KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams;
// Automatic output effects are unique for audiosession ID
- KeyedVector< audio_session_t, EffectVector* > mOutputSessions;
+ KeyedVector< int32_t, EffectVector* > mOutputSessions;
};
}; // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index e08c952..c7486a5 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -349,27 +349,8 @@
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- AudioPolicyInterface::concurrency_type__mask_t concurrency;
- status_t status = mAudioPolicyManager->startInput(input, session, &concurrency);
- if (status == NO_ERROR) {
- // enforce permission (if any) required for each type of concurrency
- switch (concurrency) {
- case AudioPolicyInterface::API_INPUT_CONCURRENCY_NONE:
- break;
- case AudioPolicyInterface::API_INPUT_CONCURRENCY_CALL:
- //TODO: check incall capture permission
- break;
- case AudioPolicyInterface::API_INPUT_CONCURRENCY_CAPTURE:
- //TODO: check concurrent capture permission
- break;
- default:
- LOG_ALWAYS_FATAL("startInput() encountered an invalid input type %d",
- (int)concurrency);
- }
- }
-
- return status;
+ return mAudioPolicyManager->startInput(input, session);
}
status_t AudioPolicyService::stopInput(audio_io_handle_t input,
@@ -397,7 +378,7 @@
}
if (audioPolicyEffects != 0) {
// release audio processors from the input
- status_t status = audioPolicyEffects->releaseInputEffects(input, session);
+ status_t status = audioPolicyEffects->releaseInputEffects(input);
if(status != NO_ERROR) {
ALOGW("Failed to release effects on input %d", input);
}
@@ -570,8 +551,7 @@
*count = 0;
return NO_INIT;
}
- return audioPolicyEffects->queryDefaultInputEffects(
- (audio_session_t)audioSession, descriptors, count);
+ return audioPolicyEffects->queryDefaultInputEffects(audioSession, descriptors, count);
}
bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
index 42719f6..08b2a3b 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImplLegacy.cpp
@@ -306,7 +306,7 @@
}
void AudioPolicyService::releaseInput(audio_io_handle_t input,
- audio_session_t session)
+ audio_session_t session __unused)
{
if (mpAudioPolicy == NULL) {
return;
@@ -320,7 +320,7 @@
}
if (audioPolicyEffects != 0) {
// release audio processors from the input
- status_t status = audioPolicyEffects->releaseInputEffects(input, session);
+ status_t status = audioPolicyEffects->releaseInputEffects(input);
if(status != NO_ERROR) {
ALOGW("Failed to release effects on input %d", input);
}