|
|
|
@ -1444,6 +1444,26 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
"session %d, flags %#x",
|
|
|
|
|
attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
|
|
|
|
|
|
|
|
|
|
status_t status = NO_ERROR;
|
|
|
|
|
// handle legacy remote submix case where the address was not always specified
|
|
|
|
|
String8 address = String8("");
|
|
|
|
|
audio_source_t halInputSource;
|
|
|
|
|
audio_source_t inputSource = attr->source;
|
|
|
|
|
AudioMix *policyMix = NULL;
|
|
|
|
|
DeviceVector inputDevices;
|
|
|
|
|
|
|
|
|
|
// Explicit routing?
|
|
|
|
|
sp<DeviceDescriptor> deviceDesc;
|
|
|
|
|
if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
|
|
|
|
|
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, uid);
|
|
|
|
|
|
|
|
|
|
// special case for mmap capture: if an input IO handle is specified, we reuse this input if
|
|
|
|
|
// possible
|
|
|
|
|
if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) == AUDIO_INPUT_FLAG_MMAP_NOIRQ &&
|
|
|
|
@ -1451,13 +1471,15 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
ssize_t index = mInputs.indexOfKey(*input);
|
|
|
|
|
if (index < 0) {
|
|
|
|
|
ALOGW("getInputForAttr() unknown MMAP input %d", *input);
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
status = BAD_VALUE;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
|
|
|
|
|
sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
|
|
|
|
|
if (audioSession == 0) {
|
|
|
|
|
ALOGW("getInputForAttr() unknown session %d on input %d", session, *input);
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
status = BAD_VALUE;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
// For MMAP mode, the first call to getInputForAttr() is made on behalf of audioflinger.
|
|
|
|
|
// The second call is for the first active client and sets the UID. Any further call
|
|
|
|
@ -1467,30 +1489,25 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
} else if (audioSession->uid() != uid) {
|
|
|
|
|
ALOGW("getInputForAttr() bad uid %d for session %d uid %d",
|
|
|
|
|
uid, session, audioSession->uid());
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
status = INVALID_OPERATION;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
audioSession->changeOpenCount(1);
|
|
|
|
|
*inputType = API_INPUT_LEGACY;
|
|
|
|
|
if (*portId == AUDIO_PORT_HANDLE_NONE) {
|
|
|
|
|
*portId = AudioPort::getNextUniqueId();
|
|
|
|
|
}
|
|
|
|
|
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(inputDesc->mDevice);
|
|
|
|
|
inputDevices = mAvailableInputDevices.getDevicesFromType(inputDesc->mDevice);
|
|
|
|
|
*selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
|
|
|
|
|
: AUDIO_PORT_HANDLE_NONE;
|
|
|
|
|
ALOGI("%s reusing MMAP input %d for session %d", __FUNCTION__, *input, session);
|
|
|
|
|
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*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("");
|
|
|
|
|
audio_source_t inputSource = attr->source;
|
|
|
|
|
audio_source_t halInputSource;
|
|
|
|
|
AudioMix *policyMix = NULL;
|
|
|
|
|
|
|
|
|
|
if (inputSource == AUDIO_SOURCE_DEFAULT) {
|
|
|
|
|
inputSource = AUDIO_SOURCE_MIC;
|
|
|
|
|
}
|
|
|
|
@ -1501,23 +1518,13 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
*portId = AudioPort::getNextUniqueId();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Explicit routing?
|
|
|
|
|
sp<DeviceDescriptor> deviceDesc;
|
|
|
|
|
if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
|
|
|
|
|
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, uid);
|
|
|
|
|
audio_devices_t device;
|
|
|
|
|
|
|
|
|
|
if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
|
|
|
|
|
strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
|
|
|
|
|
status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
|
|
|
|
|
if (ret != NO_ERROR) {
|
|
|
|
|
return ret;
|
|
|
|
|
status = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
|
|
|
|
|
if (status != NO_ERROR) {
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
*inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
|
|
|
|
|
device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
|
|
|
|
@ -1526,7 +1533,8 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
device = getDeviceAndMixForInputSource(inputSource, &policyMix);
|
|
|
|
|
if (device == AUDIO_DEVICE_NONE) {
|
|
|
|
|
ALOGW("getInputForAttr() could not find device for source %d", inputSource);
|
|
|
|
|
return BAD_VALUE;
|
|
|
|
|
status = BAD_VALUE;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
if (policyMix != NULL) {
|
|
|
|
|
address = policyMix->mDeviceAddress;
|
|
|
|
@ -1555,11 +1563,11 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
config->sample_rate, config->format, config->channel_mask, flags,
|
|
|
|
|
policyMix);
|
|
|
|
|
if (*input == AUDIO_IO_HANDLE_NONE) {
|
|
|
|
|
mInputRoutes.removeRoute(session);
|
|
|
|
|
return INVALID_OPERATION;
|
|
|
|
|
status = INVALID_OPERATION;
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(device);
|
|
|
|
|
inputDevices = mAvailableInputDevices.getDevicesFromType(device);
|
|
|
|
|
*selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
|
|
|
|
|
: AUDIO_PORT_HANDLE_NONE;
|
|
|
|
|
|
|
|
|
@ -1567,6 +1575,10 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
|
|
|
|
|
*input, *inputType, *selectedDeviceId);
|
|
|
|
|
|
|
|
|
|
return NO_ERROR;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
mInputRoutes.removeRoute(session);
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -4683,12 +4695,13 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate
|
|
|
|
|
// scan the whole RouteMap, for each entry, convert the stream type to a strategy
|
|
|
|
|
// (getStrategy(stream)).
|
|
|
|
|
// if the strategy from the stream type in the RouteMap is the same as the argument above,
|
|
|
|
|
// and activity count is non-zero
|
|
|
|
|
// the device = the device from the descriptor in the RouteMap, and exit.
|
|
|
|
|
// and activity count is non-zero and the device in the route descriptor is available
|
|
|
|
|
// then select this device.
|
|
|
|
|
for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
|
|
|
|
|
sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
|
|
|
|
|
routing_strategy routeStrategy = getStrategy(route->mStreamType);
|
|
|
|
|
if ((routeStrategy == strategy) && route->isActive()) {
|
|
|
|
|
if ((routeStrategy == strategy) && route->isActive() &&
|
|
|
|
|
(mAvailableOutputDevices.indexOf(route->mDeviceDescriptor) >= 0)) {
|
|
|
|
|
return route->mDeviceDescriptor->type();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -5083,9 +5096,15 @@ audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t
|
|
|
|
|
|
|
|
|
|
audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
|
|
|
|
|
{
|
|
|
|
|
// Routing
|
|
|
|
|
// Scan the whole RouteMap to see if we have an explicit route:
|
|
|
|
|
// if the input source in the RouteMap is the same as the argument above,
|
|
|
|
|
// and activity count is non-zero and the device in the route descriptor is available
|
|
|
|
|
// then select this device.
|
|
|
|
|
for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
|
|
|
|
|
sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
|
|
|
|
|
if (inputSource == route->mSource && route->isActive()) {
|
|
|
|
|
if ((inputSource == route->mSource) && route->isActive() &&
|
|
|
|
|
(mAvailableInputDevices.indexOf(route->mDeviceDescriptor) >= 0)) {
|
|
|
|
|
return route->mDeviceDescriptor->type();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|