audio policy: load audio hw modules
Audio hw modules are now loaded according to configuration data read from audio_policy.conf. They are not loaded anymore from a hardcoded list in AudiFlinger. Output and input streams are opened on the hw module by which they are exposed. Also removed obsolete "acoustics" flags for input streams. Change-Id: I8dc658cc83890d3ac7d5e36c372a03732aa5b0c4
This commit is contained in:
parent
5ccdf14a85
commit
70c236c929
5 changed files with 389 additions and 225 deletions
|
@ -30,16 +30,22 @@
|
|||
|
||||
namespace android_audio_legacy {
|
||||
|
||||
audio_io_handle_t AudioPolicyCompatClient::openOutput(uint32_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
uint32_t *pFormat,
|
||||
uint32_t *pChannels,
|
||||
uint32_t *pLatencyMs,
|
||||
AudioSystem::output_flags flags)
|
||||
audio_module_handle_t AudioPolicyCompatClient::loadHwModule(const char *moduleName)
|
||||
{
|
||||
return mServiceOps->open_output(mService, pDevices, pSamplingRate, (audio_format_t *) pFormat,
|
||||
pChannels, pLatencyMs,
|
||||
(audio_policy_output_flags_t)flags);
|
||||
return mServiceOps->load_hw_module(mService, moduleName);
|
||||
}
|
||||
|
||||
audio_io_handle_t AudioPolicyCompatClient::openOutput(audio_module_handle_t module,
|
||||
audio_devices_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
audio_format_t *pFormat,
|
||||
audio_channel_mask_t *pChannelMask,
|
||||
uint32_t *pLatencyMs,
|
||||
audio_policy_output_flags_t flags)
|
||||
{
|
||||
return mServiceOps->open_output_on_module(mService, module, pDevices, pSamplingRate,
|
||||
pFormat, pChannelMask, pLatencyMs,
|
||||
flags);
|
||||
}
|
||||
|
||||
audio_io_handle_t AudioPolicyCompatClient::openDuplicateOutput(audio_io_handle_t output1,
|
||||
|
@ -63,14 +69,14 @@ status_t AudioPolicyCompatClient::restoreOutput(audio_io_handle_t output)
|
|||
return mServiceOps->restore_output(mService, output);
|
||||
}
|
||||
|
||||
audio_io_handle_t AudioPolicyCompatClient::openInput(uint32_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
uint32_t *pFormat,
|
||||
uint32_t *pChannels,
|
||||
audio_in_acoustics_t acoustics)
|
||||
audio_io_handle_t AudioPolicyCompatClient::openInput(audio_module_handle_t module,
|
||||
audio_devices_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
audio_format_t *pFormat,
|
||||
audio_channel_mask_t *pChannelMask)
|
||||
{
|
||||
return mServiceOps->open_input(mService, pDevices, pSamplingRate, (audio_format_t *) pFormat,
|
||||
pChannels, acoustics);
|
||||
return mServiceOps->open_input_on_module(mService, module, pDevices,
|
||||
pSamplingRate, pFormat, pChannelMask);
|
||||
}
|
||||
|
||||
status_t AudioPolicyCompatClient::closeInput(audio_io_handle_t input)
|
||||
|
|
|
@ -35,22 +35,25 @@ public:
|
|||
void *service) :
|
||||
mServiceOps(serviceOps) , mService(service) {}
|
||||
|
||||
virtual audio_io_handle_t openOutput(uint32_t *pDevices,
|
||||
virtual audio_module_handle_t loadHwModule(const char *moduleName);
|
||||
|
||||
virtual audio_io_handle_t openOutput(audio_module_handle_t module,
|
||||
audio_devices_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
uint32_t *pFormat,
|
||||
uint32_t *pChannels,
|
||||
audio_format_t *pFormat,
|
||||
audio_channel_mask_t *pChannelMask,
|
||||
uint32_t *pLatencyMs,
|
||||
AudioSystem::output_flags flags);
|
||||
audio_policy_output_flags_t flags);
|
||||
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
|
||||
audio_io_handle_t output2);
|
||||
virtual status_t closeOutput(audio_io_handle_t output);
|
||||
virtual status_t suspendOutput(audio_io_handle_t output);
|
||||
virtual status_t restoreOutput(audio_io_handle_t output);
|
||||
virtual audio_io_handle_t openInput(uint32_t *pDevices,
|
||||
virtual audio_io_handle_t openInput(audio_module_handle_t module,
|
||||
audio_devices_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
uint32_t *pFormat,
|
||||
uint32_t *pChannels,
|
||||
audio_in_acoustics_t acoustics);
|
||||
audio_format_t *pFormat,
|
||||
audio_channel_mask_t *pChannelMask);
|
||||
virtual status_t closeInput(audio_io_handle_t input);
|
||||
virtual status_t setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output);
|
||||
virtual status_t moveEffects(int session,
|
||||
|
|
|
@ -405,21 +405,42 @@ void AudioPolicyManagerBase::setSystemProperty(const char* property, const char*
|
|||
}
|
||||
}
|
||||
|
||||
audio_module_handle_t AudioPolicyManagerBase::getModuleForDirectoutput(audio_devices_t device,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channelMask,
|
||||
audio_policy_output_flags_t flags)
|
||||
{
|
||||
for (size_t i = 0; i < mHwModules.size(); i++) {
|
||||
if (mHwModules[i]->mHandle == 0) {
|
||||
continue;
|
||||
}
|
||||
for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
|
||||
if (mHwModules[i]->mOutputProfiles[j]->isCompatibleProfile(device, samplingRate, format,
|
||||
channelMask, flags)) {
|
||||
return mHwModules[i]->mHandle;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channels,
|
||||
uint32_t channelMask,
|
||||
AudioSystem::output_flags flags)
|
||||
{
|
||||
audio_io_handle_t output = 0;
|
||||
uint32_t latency = 0;
|
||||
routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
|
||||
audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
|
||||
ALOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
|
||||
ALOGV("getOutput() stream %d, samplingRate %d, format %d, channelMask %x, flags %x",
|
||||
stream, samplingRate, format, channelMask, flags);
|
||||
|
||||
#ifdef AUDIO_POLICY_TEST
|
||||
if (mCurOutput != 0) {
|
||||
ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d",
|
||||
ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
|
||||
mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
|
||||
|
||||
if (mTestOutputs[mCurOutput] == 0) {
|
||||
|
@ -428,14 +449,14 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
|
|||
outputDesc->mDevice = mTestDevice;
|
||||
outputDesc->mSamplingRate = mTestSamplingRate;
|
||||
outputDesc->mFormat = mTestFormat;
|
||||
outputDesc->mChannels = mTestChannels;
|
||||
outputDesc->mChannelMask = mTestChannels;
|
||||
outputDesc->mLatency = mTestLatencyMs;
|
||||
outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
|
||||
outputDesc->mFlags = (audio_policy_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
|
||||
outputDesc->mRefCount[stream] = 0;
|
||||
mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice,
|
||||
mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
|
||||
&outputDesc->mSamplingRate,
|
||||
&outputDesc->mFormat,
|
||||
&outputDesc->mChannels,
|
||||
&outputDesc->mChannelMask,
|
||||
&outputDesc->mLatency,
|
||||
outputDesc->mFlags);
|
||||
if (mTestOutputs[mCurOutput]) {
|
||||
|
@ -450,22 +471,37 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
|
|||
#endif //AUDIO_POLICY_TEST
|
||||
|
||||
// open a direct output if required by specified parameters
|
||||
if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) {
|
||||
if (needsDirectOuput((audio_stream_type_t)stream,
|
||||
samplingRate,
|
||||
(audio_format_t)format,
|
||||
(audio_channel_mask_t)channelMask,
|
||||
(audio_policy_output_flags_t)flags,
|
||||
device)) {
|
||||
|
||||
ALOGV("getOutput() opening direct output device %x", device);
|
||||
|
||||
audio_module_handle_t module = getModuleForDirectoutput(device,
|
||||
samplingRate,
|
||||
format,
|
||||
channelMask,
|
||||
(audio_policy_output_flags_t)flags);
|
||||
if (module == 0) {
|
||||
return 0;
|
||||
}
|
||||
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
|
||||
outputDesc->mDevice = device;
|
||||
outputDesc->mSamplingRate = samplingRate;
|
||||
outputDesc->mFormat = format;
|
||||
outputDesc->mChannels = channels;
|
||||
outputDesc->mFormat = (audio_format_t)format;
|
||||
outputDesc->mChannelMask = (audio_channel_mask_t)channelMask;
|
||||
outputDesc->mLatency = 0;
|
||||
outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
|
||||
outputDesc->mFlags = (audio_policy_output_flags_t)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
|
||||
outputDesc->mRefCount[stream] = 0;
|
||||
outputDesc->mStopTime[stream] = 0;
|
||||
output = mpClientInterface->openOutput((uint32_t *)&outputDesc->mDevice,
|
||||
output = mpClientInterface->openOutput(module,
|
||||
&outputDesc->mDevice,
|
||||
&outputDesc->mSamplingRate,
|
||||
&outputDesc->mFormat,
|
||||
&outputDesc->mChannels,
|
||||
&outputDesc->mChannelMask,
|
||||
&outputDesc->mLatency,
|
||||
outputDesc->mFlags);
|
||||
|
||||
|
@ -473,9 +509,9 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
|
|||
if (output == 0 ||
|
||||
(samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
|
||||
(format != 0 && format != outputDesc->mFormat) ||
|
||||
(channels != 0 && channels != outputDesc->mChannels)) {
|
||||
ALOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d",
|
||||
samplingRate, format, channels);
|
||||
(channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
|
||||
ALOGV("getOutput() failed opening direct output: samplingRate %d,"
|
||||
"format %d, channelMask %d", samplingRate, format, channelMask);
|
||||
if (output != 0) {
|
||||
mpClientInterface->closeOutput(output);
|
||||
}
|
||||
|
@ -486,8 +522,8 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
|
|||
return output;
|
||||
}
|
||||
|
||||
if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
|
||||
channels != AudioSystem::CHANNEL_OUT_STEREO) {
|
||||
if (channelMask != 0 && channelMask != AudioSystem::CHANNEL_OUT_MONO &&
|
||||
channelMask != AudioSystem::CHANNEL_OUT_STEREO) {
|
||||
return 0;
|
||||
}
|
||||
// open a non direct output
|
||||
|
@ -498,8 +534,8 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str
|
|||
|
||||
output = selectOutput(outputs, flags);
|
||||
|
||||
ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x",
|
||||
stream, samplingRate, format, channels, flags);
|
||||
ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d,"
|
||||
"format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
|
||||
|
||||
ALOGV("getOutput() returns output %d", output);
|
||||
|
||||
|
@ -701,14 +737,14 @@ void AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output)
|
|||
audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channels,
|
||||
uint32_t channelMask,
|
||||
AudioSystem::audio_in_acoustics acoustics)
|
||||
{
|
||||
audio_io_handle_t input = 0;
|
||||
audio_devices_t device = getDeviceForInputSource(inputSource);
|
||||
|
||||
ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x",
|
||||
inputSource, samplingRate, format, channels, acoustics);
|
||||
ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x",
|
||||
inputSource, samplingRate, format, channelMask, acoustics);
|
||||
|
||||
if (device == 0) {
|
||||
ALOGW("getInput() could not find device for inputSource %d", inputSource);
|
||||
|
@ -718,13 +754,13 @@ audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
|
|||
// adapt channel selection to input source
|
||||
switch(inputSource) {
|
||||
case AUDIO_SOURCE_VOICE_UPLINK:
|
||||
channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
|
||||
channelMask = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
|
||||
break;
|
||||
case AUDIO_SOURCE_VOICE_DOWNLINK:
|
||||
channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
|
||||
channelMask = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
|
||||
break;
|
||||
case AUDIO_SOURCE_VOICE_CALL:
|
||||
channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
|
||||
channelMask = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -733,11 +769,17 @@ audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
|
|||
IOProfile *profile = getInputProfile(device,
|
||||
samplingRate,
|
||||
format,
|
||||
channels);
|
||||
channelMask);
|
||||
if (profile == NULL) {
|
||||
ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d,"
|
||||
"channels %04x",
|
||||
device, samplingRate, format, channels);
|
||||
"channelMask %04x",
|
||||
device, samplingRate, format, channelMask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (profile->mModule->mHandle == 0) {
|
||||
ALOGE("checkOutputForDevice(): could not open HW module %s",
|
||||
profile->mModule->mName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -746,23 +788,22 @@ audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
|
|||
inputDesc->mInputSource = inputSource;
|
||||
inputDesc->mDevice = device;
|
||||
inputDesc->mSamplingRate = samplingRate;
|
||||
inputDesc->mFormat = format;
|
||||
inputDesc->mChannels = channels;
|
||||
inputDesc->mAcoustics = acoustics;
|
||||
inputDesc->mFormat = (audio_format_t)format;
|
||||
inputDesc->mChannelMask = (audio_channel_mask_t)channelMask;
|
||||
inputDesc->mRefCount = 0;
|
||||
input = mpClientInterface->openInput((uint32_t *)&inputDesc->mDevice,
|
||||
input = mpClientInterface->openInput(profile->mModule->mHandle,
|
||||
&inputDesc->mDevice,
|
||||
&inputDesc->mSamplingRate,
|
||||
&inputDesc->mFormat,
|
||||
&inputDesc->mChannels,
|
||||
(audio_in_acoustics_t) inputDesc->mAcoustics);
|
||||
&inputDesc->mChannelMask);
|
||||
|
||||
// only accept input with the exact requested set of parameters
|
||||
if (input == 0 ||
|
||||
(samplingRate != inputDesc->mSamplingRate) ||
|
||||
(format != inputDesc->mFormat) ||
|
||||
(channels != inputDesc->mChannels)) {
|
||||
ALOGV("getInput() failed opening input: samplingRate %d, format %d, channels %d",
|
||||
samplingRate, format, channels);
|
||||
(channelMask != inputDesc->mChannelMask)) {
|
||||
ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d",
|
||||
samplingRate, format, channelMask);
|
||||
if (input != 0) {
|
||||
mpClientInterface->closeInput(input);
|
||||
}
|
||||
|
@ -1050,7 +1091,7 @@ status_t AudioPolicyManagerBase::dump(int fd)
|
|||
snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
|
||||
result.append(buffer);
|
||||
|
||||
snprintf(buffer, SIZE, " Hardware Output: %d\n", mPrimaryOutput);
|
||||
snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string());
|
||||
result.append(buffer);
|
||||
|
@ -1072,20 +1113,13 @@ status_t AudioPolicyManagerBase::dump(int fd)
|
|||
result.append(buffer);
|
||||
write(fd, result.string(), result.size());
|
||||
|
||||
snprintf(buffer, SIZE, "\nOutput Profiles dump:\n");
|
||||
write(fd, buffer, strlen(buffer));
|
||||
for (size_t i = 0; i < mOutputProfiles.size(); i++) {
|
||||
snprintf(buffer, SIZE, "- Output Profile %d:\n", i + 1);
|
||||
write(fd, buffer, strlen(buffer));
|
||||
mOutputProfiles[i]->dump(fd);
|
||||
}
|
||||
|
||||
snprintf(buffer, SIZE, "\nInput Profiles dump:\n");
|
||||
snprintf(buffer, SIZE, "\nHW Modules dump:\n");
|
||||
write(fd, buffer, strlen(buffer));
|
||||
for (size_t i = 0; i < mInputProfiles.size(); i++) {
|
||||
snprintf(buffer, SIZE, "- Input Profile %d:\n", i + 1);
|
||||
for (size_t i = 0; i < mHwModules.size(); i++) {
|
||||
snprintf(buffer, SIZE, "- HW Module %d:\n", i + 1);
|
||||
write(fd, buffer, strlen(buffer));
|
||||
mInputProfiles[i]->dump(fd);
|
||||
mHwModules[i]->dump(fd);
|
||||
}
|
||||
|
||||
snprintf(buffer, SIZE, "\nOutputs dump:\n");
|
||||
|
@ -1140,6 +1174,7 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien
|
|||
#ifdef AUDIO_POLICY_TEST
|
||||
Thread(false),
|
||||
#endif //AUDIO_POLICY_TEST
|
||||
mPrimaryOutput((audio_io_handle_t)0),
|
||||
mAvailableOutputDevices((audio_devices_t)0),
|
||||
mPhoneState(AudioSystem::MODE_NORMAL),
|
||||
mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
|
||||
|
@ -1162,39 +1197,49 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien
|
|||
}
|
||||
|
||||
// open all output streams needed to access attached devices
|
||||
for (size_t i = 0; i < mOutputProfiles.size(); i++)
|
||||
{
|
||||
const IOProfile *outProfile = mOutputProfiles[i];
|
||||
for (size_t i = 0; i < mHwModules.size(); i++) {
|
||||
mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
|
||||
if (mHwModules[i]->mHandle == 0) {
|
||||
ALOGW("could not open HW module %s", mHwModules[i]->mName);
|
||||
continue;
|
||||
}
|
||||
// open all output streams needed to access attached devices
|
||||
for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
|
||||
{
|
||||
const IOProfile *outProfile = mHwModules[i]->mOutputProfiles[j];
|
||||
|
||||
if (outProfile->mSupportedDevices & mAttachedOutputDevices) {
|
||||
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
|
||||
if (outProfile->mSupportedDevices & mAttachedOutputDevices) {
|
||||
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
|
||||
|
||||
outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice &
|
||||
outProfile->mSupportedDevices);
|
||||
outputDesc->mSamplingRate = outProfile->mSamplingRates[0];
|
||||
outputDesc->mFormat = outProfile->mFormats[0];
|
||||
outputDesc->mChannels = outProfile->mChannelMasks[0];
|
||||
outputDesc->mFlags = (AudioSystem::output_flags)outProfile->mFlags;
|
||||
audio_io_handle_t output = mpClientInterface->openOutput(
|
||||
(uint32_t *)&outputDesc->mDevice,
|
||||
&outputDesc->mSamplingRate,
|
||||
&outputDesc->mFormat,
|
||||
&outputDesc->mChannels,
|
||||
&outputDesc->mLatency,
|
||||
outputDesc->mFlags);
|
||||
if (output == 0) {
|
||||
delete outputDesc;
|
||||
} else {
|
||||
mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices |
|
||||
(outProfile->mSupportedDevices & mAttachedOutputDevices));
|
||||
if (outProfile->mFlags & AUDIO_POLICY_OUTPUT_FLAG_PRIMARY) {
|
||||
mPrimaryOutput = output;
|
||||
outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice &
|
||||
outProfile->mSupportedDevices);
|
||||
outputDesc->mSamplingRate = outProfile->mSamplingRates[0];
|
||||
outputDesc->mFormat = outProfile->mFormats[0];
|
||||
outputDesc->mChannelMask = outProfile->mChannelMasks[0];
|
||||
outputDesc->mFlags = outProfile->mFlags;
|
||||
audio_io_handle_t output = mpClientInterface->openOutput(
|
||||
outProfile->mModule->mHandle,
|
||||
&outputDesc->mDevice,
|
||||
&outputDesc->mSamplingRate,
|
||||
&outputDesc->mFormat,
|
||||
&outputDesc->mChannelMask,
|
||||
&outputDesc->mLatency,
|
||||
outputDesc->mFlags);
|
||||
if (output == 0) {
|
||||
delete outputDesc;
|
||||
} else {
|
||||
mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices |
|
||||
(outProfile->mSupportedDevices & mAttachedOutputDevices));
|
||||
if (mPrimaryOutput == 0 &&
|
||||
outProfile->mFlags & AUDIO_POLICY_OUTPUT_FLAG_PRIMARY) {
|
||||
mPrimaryOutput = output;
|
||||
}
|
||||
addOutput(output, outputDesc);
|
||||
setOutputDevice(output,
|
||||
(audio_devices_t)(mDefaultOutputDevice &
|
||||
outProfile->mSupportedDevices),
|
||||
true);
|
||||
}
|
||||
addOutput(output, outputDesc);
|
||||
setOutputDevice(output,
|
||||
(audio_devices_t)(mDefaultOutputDevice &
|
||||
outProfile->mSupportedDevices),
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1240,17 +1285,12 @@ AudioPolicyManagerBase::~AudioPolicyManagerBase()
|
|||
mpClientInterface->closeOutput(mOutputs.keyAt(i));
|
||||
delete mOutputs.valueAt(i);
|
||||
}
|
||||
mOutputs.clear();
|
||||
for (size_t i = 0; i < mInputs.size(); i++) {
|
||||
mpClientInterface->closeInput(mInputs.keyAt(i));
|
||||
delete mInputs.valueAt(i);
|
||||
}
|
||||
mInputs.clear();
|
||||
for (size_t i = 0; i < mOutputProfiles.size(); i++) {
|
||||
delete mOutputProfiles[i];
|
||||
}
|
||||
for (size_t i = 0; i < mInputProfiles.size(); i++) {
|
||||
delete mInputProfiles[i];
|
||||
for (size_t i = 0; i < mHwModules.size(); i++) {
|
||||
delete mHwModules[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1355,21 +1395,26 @@ bool AudioPolicyManagerBase::threadLoop()
|
|||
if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
|
||||
param.remove(String8("test_cmd_policy_reopen"));
|
||||
|
||||
AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
|
||||
mpClientInterface->closeOutput(mPrimaryOutput);
|
||||
|
||||
audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
|
||||
|
||||
delete mOutputs.valueFor(mPrimaryOutput);
|
||||
mOutputs.removeItem(mPrimaryOutput);
|
||||
|
||||
AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
|
||||
outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
|
||||
mPrimaryOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
|
||||
mPrimaryOutput = mpClientInterface->openOutput(moduleHandle,
|
||||
&outputDesc->mDevice,
|
||||
&outputDesc->mSamplingRate,
|
||||
&outputDesc->mFormat,
|
||||
&outputDesc->mChannels,
|
||||
&outputDesc->mChannelMask,
|
||||
&outputDesc->mLatency,
|
||||
outputDesc->mFlags);
|
||||
if (mPrimaryOutput == 0) {
|
||||
ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
|
||||
outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
|
||||
outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
|
||||
} else {
|
||||
AudioParameter outputCmd = AudioParameter();
|
||||
outputCmd.addInt(String8("set_id"), 0);
|
||||
|
@ -1432,25 +1477,42 @@ audio_io_handle_t AudioPolicyManagerBase::checkOutputForDevice(
|
|||
}
|
||||
// then look for one available output that can be routed to this device
|
||||
const IOProfile *outProfile = NULL;
|
||||
for (size_t i = 0; i < mOutputProfiles.size(); i++)
|
||||
for (size_t i = 0; i < mHwModules.size(); i++)
|
||||
{
|
||||
if (mOutputProfiles[i]->mSupportedDevices & device) {
|
||||
outProfile = mOutputProfiles[i];
|
||||
if (mHwModules[i]->mHandle == 0) {
|
||||
continue;
|
||||
}
|
||||
for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
|
||||
{
|
||||
if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) {
|
||||
outProfile = mHwModules[i]->mOutputProfiles[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (outProfile != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outProfile == NULL) {
|
||||
ALOGW("No output available for device %04x", device);
|
||||
ALOGW("checkOutputForDevice(): No output available for device %04x", device);
|
||||
return output;
|
||||
}
|
||||
|
||||
if (outProfile->mModule->mHandle == 0) {
|
||||
ALOGE("checkOutputForDevice(): could not open HW module %s",
|
||||
outProfile->mModule->mName);
|
||||
return output;
|
||||
}
|
||||
|
||||
ALOGV("opening output for device %08x", device);
|
||||
outputDesc = new AudioOutputDescriptor(outProfile);
|
||||
outputDesc->mDevice = device;
|
||||
output = mpClientInterface->openOutput((uint32_t *)&outputDesc->mDevice,
|
||||
output = mpClientInterface->openOutput(outProfile->mModule->mHandle,
|
||||
&outputDesc->mDevice,
|
||||
&outputDesc->mSamplingRate,
|
||||
&outputDesc->mFormat,
|
||||
&outputDesc->mChannels,
|
||||
&outputDesc->mChannelMask,
|
||||
&outputDesc->mLatency,
|
||||
outputDesc->mFlags);
|
||||
|
||||
|
@ -1472,7 +1534,7 @@ audio_io_handle_t AudioPolicyManagerBase::checkOutputForDevice(
|
|||
dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
|
||||
dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate;
|
||||
dupOutputDesc->mFormat = outputDesc->mFormat;
|
||||
dupOutputDesc->mChannels = outputDesc->mChannels;
|
||||
dupOutputDesc->mChannelMask = outputDesc->mChannelMask;
|
||||
dupOutputDesc->mLatency = outputDesc->mLatency;
|
||||
addOutput(duplicatedOutput, dupOutputDesc);
|
||||
applyStreamVolumes(duplicatedOutput, device);
|
||||
|
@ -1591,7 +1653,6 @@ void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy)
|
|||
getOutputsForDevice(getDeviceForStrategy(strategy, false /*fromCache*/));
|
||||
|
||||
if (!vectorsEqual(srcOutputs,dstOutputs)) {
|
||||
// FIXME dstOutputs[0] happens to be the output to use, what guarantees it is always true?
|
||||
ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
|
||||
strategy, srcOutputs[0], dstOutputs[0]);
|
||||
// mute strategy while moving tracks from one output to another
|
||||
|
@ -2072,56 +2133,24 @@ AudioPolicyManagerBase::IOProfile *AudioPolicyManagerBase::getInputProfile(audio
|
|||
uint32_t format,
|
||||
uint32_t channelMask)
|
||||
{
|
||||
IOProfile *inProfile = NULL;
|
||||
|
||||
// Choose an input profile based on the requested capture parameters: select the first available
|
||||
// profile supporting all requested parameters.
|
||||
|
||||
for (size_t i = 0; i < mInputProfiles.size(); i++)
|
||||
for (size_t i = 0; i < mHwModules.size(); i++)
|
||||
{
|
||||
IOProfile *profile = mInputProfiles[i];
|
||||
size_t j;
|
||||
if ((profile->mSupportedDevices & device) == 0) {
|
||||
if (mHwModules[i]->mHandle == 0) {
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < profile->mSamplingRates.size(); j++)
|
||||
for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
|
||||
{
|
||||
if (profile->mSamplingRates[j] == samplingRate) {
|
||||
break;
|
||||
IOProfile *profile = mHwModules[i]->mInputProfiles[j];
|
||||
if (profile->isCompatibleProfile(device, samplingRate, format,
|
||||
channelMask,(audio_policy_output_flags_t)0)) {
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
if (j == profile->mSamplingRates.size()) {
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < profile->mFormats.size(); j++)
|
||||
{
|
||||
if (profile->mFormats[j] == format) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == profile->mFormats.size()) {
|
||||
continue;
|
||||
}
|
||||
for (j = 0; j < profile->mChannelMasks.size(); j++)
|
||||
{
|
||||
if (profile->mChannelMasks[j] == channelMask) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == profile->mChannelMasks.size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
inProfile = profile;
|
||||
break;
|
||||
}
|
||||
ALOGW_IF(inProfile == NULL, "getInputProfile() no available input for device %04x"
|
||||
"samplingRate %d, format %d channel mask %04x",
|
||||
device,
|
||||
samplingRate,
|
||||
format,
|
||||
channelMask);
|
||||
return inProfile;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource)
|
||||
|
@ -2570,12 +2599,12 @@ bool AudioPolicyManagerBase::isStateInCall(int state) {
|
|||
(state == AudioSystem::MODE_IN_COMMUNICATION));
|
||||
}
|
||||
|
||||
bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channels,
|
||||
AudioSystem::output_flags flags,
|
||||
uint32_t device)
|
||||
bool AudioPolicyManagerBase::needsDirectOuput(audio_stream_type_t stream,
|
||||
uint32_t samplingRate,
|
||||
audio_format_t format,
|
||||
audio_channel_mask_t channelMask,
|
||||
audio_policy_output_flags_t flags,
|
||||
audio_devices_t device)
|
||||
{
|
||||
return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
|
||||
(format != 0 && !AudioSystem::isLinearPCM(format)));
|
||||
|
@ -2595,8 +2624,9 @@ uint32_t AudioPolicyManagerBase::getMaxEffectsMemory()
|
|||
|
||||
AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor(
|
||||
const IOProfile *profile)
|
||||
: mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
|
||||
mFlags((AudioSystem::output_flags)0), mDevice((audio_devices_t)0),
|
||||
: mId(0), mSamplingRate(0), mFormat((audio_format_t)0),
|
||||
mChannelMask((audio_channel_mask_t)0), mLatency(0),
|
||||
mFlags((audio_policy_output_flags_t)0), mDevice((audio_devices_t)0),
|
||||
mOutput1(0), mOutput2(0), mProfile(profile)
|
||||
{
|
||||
// clear usage count for all stream types
|
||||
|
@ -2634,7 +2664,7 @@ bool AudioPolicyManagerBase::AudioOutputDescriptor::sharesHwModuleWith(
|
|||
} else if (outputDesc->isDuplicated()){
|
||||
return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
|
||||
} else {
|
||||
return strcmp(mProfile->mModuleName, outputDesc->mProfile->mModuleName) == 0;
|
||||
return (mProfile->mModule == outputDesc->mProfile->mModule);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2693,7 +2723,7 @@ status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
|
|||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " Format: %d\n", mFormat);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
|
||||
snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
|
||||
result.append(buffer);
|
||||
|
@ -2715,8 +2745,8 @@ status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
|
|||
// --- AudioInputDescriptor class implementation
|
||||
|
||||
AudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor(const IOProfile *profile)
|
||||
: mSamplingRate(0), mFormat(0), mChannels(0),
|
||||
mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice((audio_devices_t)0), mRefCount(0),
|
||||
: mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0),
|
||||
mDevice((audio_devices_t)0), mRefCount(0),
|
||||
mInputSource(0), mProfile(profile)
|
||||
{
|
||||
}
|
||||
|
@ -2731,9 +2761,7 @@ status_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd)
|
|||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " Format: %d\n", mFormat);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
|
||||
snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
|
||||
result.append(buffer);
|
||||
|
@ -2807,15 +2835,107 @@ status_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd)
|
|||
|
||||
// --- IOProfile class implementation
|
||||
|
||||
AudioPolicyManagerBase::IOProfile::IOProfile(const char *module)
|
||||
: mFlags((audio_policy_output_flags_t)0),
|
||||
mModuleName(strndup(module, AUDIO_HARDWARE_MODULE_ID_MAX_LEN))
|
||||
AudioPolicyManagerBase::HwModule::HwModule(const char *name)
|
||||
: mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0)
|
||||
{
|
||||
}
|
||||
|
||||
AudioPolicyManagerBase::HwModule::~HwModule()
|
||||
{
|
||||
for (size_t i = 0; i < mOutputProfiles.size(); i++) {
|
||||
delete mOutputProfiles[i];
|
||||
}
|
||||
for (size_t i = 0; i < mInputProfiles.size(); i++) {
|
||||
delete mInputProfiles[i];
|
||||
}
|
||||
free((void *)mName);
|
||||
}
|
||||
|
||||
void AudioPolicyManagerBase::HwModule::dump(int fd)
|
||||
{
|
||||
const size_t SIZE = 256;
|
||||
char buffer[SIZE];
|
||||
String8 result;
|
||||
|
||||
snprintf(buffer, SIZE, " - name: %s\n", mName);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " - handle: %d\n", mHandle);
|
||||
result.append(buffer);
|
||||
write(fd, result.string(), result.size());
|
||||
if (mOutputProfiles.size()) {
|
||||
write(fd, " - outputs:\n", sizeof(" - outputs:\n"));
|
||||
for (size_t i = 0; i < mOutputProfiles.size(); i++) {
|
||||
mOutputProfiles[i]->dump(fd);
|
||||
}
|
||||
}
|
||||
if (mInputProfiles.size()) {
|
||||
write(fd, " - inputs:\n", sizeof(" - inputs:\n"));
|
||||
for (size_t i = 0; i < mInputProfiles.size(); i++) {
|
||||
mInputProfiles[i]->dump(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AudioPolicyManagerBase::IOProfile::IOProfile(HwModule *module)
|
||||
: mFlags((audio_policy_output_flags_t)0), mModule(module)
|
||||
{
|
||||
}
|
||||
|
||||
AudioPolicyManagerBase::IOProfile::~IOProfile()
|
||||
{
|
||||
free(mModuleName);
|
||||
}
|
||||
|
||||
// checks if the IO profile is compatible with specified parameters. By convention a value of 0
|
||||
// means a parameter is don't care
|
||||
bool AudioPolicyManagerBase::IOProfile::isCompatibleProfile(audio_devices_t device,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channelMask,
|
||||
audio_policy_output_flags_t flags) const
|
||||
{
|
||||
if ((mSupportedDevices & device) != device) {
|
||||
return false;
|
||||
}
|
||||
if ((mFlags & flags) != flags) {
|
||||
return false;
|
||||
}
|
||||
if (samplingRate != 0) {
|
||||
size_t i;
|
||||
for (i = 0; i < mSamplingRates.size(); i++)
|
||||
{
|
||||
if (mSamplingRates[i] == samplingRate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == mSamplingRates.size()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (format != 0) {
|
||||
size_t i;
|
||||
for (i = 0; i < mFormats.size(); i++)
|
||||
{
|
||||
if (mFormats[i] == format) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == mFormats.size()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (channelMask != 0) {
|
||||
size_t i;
|
||||
for (i = 0; i < mChannelMasks.size(); i++)
|
||||
{
|
||||
if (mChannelMasks[i] == channelMask) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == mChannelMasks.size()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioPolicyManagerBase::IOProfile::dump(int fd)
|
||||
|
@ -2824,7 +2944,7 @@ void AudioPolicyManagerBase::IOProfile::dump(int fd)
|
|||
char buffer[SIZE];
|
||||
String8 result;
|
||||
|
||||
snprintf(buffer, SIZE, " - sampling rates: ");
|
||||
snprintf(buffer, SIZE, " - sampling rates: ");
|
||||
result.append(buffer);
|
||||
for (size_t i = 0; i < mSamplingRates.size(); i++) {
|
||||
snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
|
||||
|
@ -2832,7 +2952,7 @@ void AudioPolicyManagerBase::IOProfile::dump(int fd)
|
|||
result.append(i == (mSamplingRates.size() - 1) ? "\n" : ", ");
|
||||
}
|
||||
|
||||
snprintf(buffer, SIZE, " - channel masks: ");
|
||||
snprintf(buffer, SIZE, " - channel masks: ");
|
||||
result.append(buffer);
|
||||
for (size_t i = 0; i < mChannelMasks.size(); i++) {
|
||||
snprintf(buffer, SIZE, "%04x", mChannelMasks[i]);
|
||||
|
@ -2840,7 +2960,7 @@ void AudioPolicyManagerBase::IOProfile::dump(int fd)
|
|||
result.append(i == (mChannelMasks.size() - 1) ? "\n" : ", ");
|
||||
}
|
||||
|
||||
snprintf(buffer, SIZE, " - formats: ");
|
||||
snprintf(buffer, SIZE, " - formats: ");
|
||||
result.append(buffer);
|
||||
for (size_t i = 0; i < mFormats.size(); i++) {
|
||||
snprintf(buffer, SIZE, "%d", mFormats[i]);
|
||||
|
@ -2848,11 +2968,9 @@ void AudioPolicyManagerBase::IOProfile::dump(int fd)
|
|||
result.append(i == (mFormats.size() - 1) ? "\n" : ", ");
|
||||
}
|
||||
|
||||
snprintf(buffer, SIZE, " - devices: %04x\n", mSupportedDevices);
|
||||
snprintf(buffer, SIZE, " - devices: %04x\n", mSupportedDevices);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " - flags: %04x\n", mFlags);
|
||||
result.append(buffer);
|
||||
snprintf(buffer, SIZE, " - hw module: %s\n", mModuleName);
|
||||
snprintf(buffer, SIZE, " - flags: %04x\n", mFlags);
|
||||
result.append(buffer);
|
||||
|
||||
write(fd, result.string(), result.size());
|
||||
|
@ -3025,7 +3143,7 @@ void AudioPolicyManagerBase::loadOutChannels(char *name, IOProfile *profile)
|
|||
return;
|
||||
}
|
||||
|
||||
status_t AudioPolicyManagerBase::loadInput(cnode *root, const char *module)
|
||||
status_t AudioPolicyManagerBase::loadInput(cnode *root, HwModule *module)
|
||||
{
|
||||
cnode *node = root->first_child;
|
||||
|
||||
|
@ -3058,7 +3176,7 @@ status_t AudioPolicyManagerBase::loadInput(cnode *root, const char *module)
|
|||
|
||||
ALOGV("loadInput() adding input mSupportedDevices %04x", profile->mSupportedDevices);
|
||||
|
||||
mInputProfiles.add(profile);
|
||||
module->mInputProfiles.add(profile);
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
delete profile;
|
||||
|
@ -3066,7 +3184,7 @@ status_t AudioPolicyManagerBase::loadInput(cnode *root, const char *module)
|
|||
}
|
||||
}
|
||||
|
||||
status_t AudioPolicyManagerBase::loadOutput(cnode *root, const char *module)
|
||||
status_t AudioPolicyManagerBase::loadOutput(cnode *root, HwModule *module)
|
||||
{
|
||||
cnode *node = root->first_child;
|
||||
|
||||
|
@ -3102,7 +3220,7 @@ status_t AudioPolicyManagerBase::loadOutput(cnode *root, const char *module)
|
|||
ALOGV("loadOutput() adding output mSupportedDevices %04x, mFlags %04x",
|
||||
profile->mSupportedDevices, profile->mFlags);
|
||||
|
||||
mOutputProfiles.add(profile);
|
||||
module->mOutputProfiles.add(profile);
|
||||
return NO_ERROR;
|
||||
} else {
|
||||
delete profile;
|
||||
|
@ -3114,6 +3232,9 @@ void AudioPolicyManagerBase::loadHwModule(cnode *root)
|
|||
{
|
||||
cnode *node = config_find(root, OUTPUTS_TAG);
|
||||
status_t status = NAME_NOT_FOUND;
|
||||
|
||||
HwModule *module = new HwModule(root->name);
|
||||
|
||||
if (node != NULL) {
|
||||
if (strcmp(root->name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) {
|
||||
mHasA2dp = true;
|
||||
|
@ -3121,7 +3242,7 @@ void AudioPolicyManagerBase::loadHwModule(cnode *root)
|
|||
node = node->first_child;
|
||||
while (node) {
|
||||
ALOGV("loadHwModule() loading output %s", node->name);
|
||||
status_t tmpStatus = loadOutput(node, root->name);
|
||||
status_t tmpStatus = loadOutput(node, module);
|
||||
if (status == NAME_NOT_FOUND || status == NO_ERROR) {
|
||||
status = tmpStatus;
|
||||
}
|
||||
|
@ -3133,7 +3254,7 @@ void AudioPolicyManagerBase::loadHwModule(cnode *root)
|
|||
node = node->first_child;
|
||||
while (node) {
|
||||
ALOGV("loadHwModule() loading input %s", node->name);
|
||||
status_t tmpStatus = loadInput(node, root->name);
|
||||
status_t tmpStatus = loadInput(node, module);
|
||||
if (status == NAME_NOT_FOUND || status == NO_ERROR) {
|
||||
status = tmpStatus;
|
||||
}
|
||||
|
@ -3141,7 +3262,9 @@ void AudioPolicyManagerBase::loadHwModule(cnode *root)
|
|||
}
|
||||
}
|
||||
if (status == NO_ERROR) {
|
||||
//TODO: load HW module via audioflinger
|
||||
mHwModules.add(module);
|
||||
} else {
|
||||
delete module;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,13 @@ class AudioPolicyClientInterface
|
|||
public:
|
||||
virtual ~AudioPolicyClientInterface() {}
|
||||
|
||||
//
|
||||
// Audio HW module functions
|
||||
//
|
||||
|
||||
// loads a HW module.
|
||||
virtual audio_module_handle_t loadHwModule(const char *name) = 0;
|
||||
|
||||
//
|
||||
// Audio output Control functions
|
||||
//
|
||||
|
@ -177,12 +184,13 @@ public:
|
|||
// in case the audio policy manager has no specific requirements for the output being opened.
|
||||
// When the function returns, the parameter values reflect the actual values used by the audio hardware output stream.
|
||||
// The audio policy manager can check if the proposed parameters are suitable or not and act accordingly.
|
||||
virtual audio_io_handle_t openOutput(uint32_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
uint32_t *pFormat,
|
||||
uint32_t *pChannels,
|
||||
uint32_t *pLatencyMs,
|
||||
AudioSystem::output_flags flags) = 0;
|
||||
virtual audio_io_handle_t openOutput(audio_module_handle_t module,
|
||||
audio_devices_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
audio_format_t *pFormat,
|
||||
audio_channel_mask_t *pChannelMask,
|
||||
uint32_t *pLatencyMs,
|
||||
audio_policy_output_flags_t flags) = 0;
|
||||
// creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
|
||||
// a special mixer thread in the AudioFlinger.
|
||||
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2) = 0;
|
||||
|
@ -199,11 +207,11 @@ public:
|
|||
//
|
||||
|
||||
// opens an audio input
|
||||
virtual audio_io_handle_t openInput(uint32_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
uint32_t *pFormat,
|
||||
uint32_t *pChannels,
|
||||
audio_in_acoustics_t acoustics) = 0;
|
||||
virtual audio_io_handle_t openInput(audio_module_handle_t module,
|
||||
audio_devices_t *pDevices,
|
||||
uint32_t *pSamplingRate,
|
||||
audio_format_t *pFormat,
|
||||
audio_channel_mask_t *pChannelMask) = 0;
|
||||
// closes an audio input
|
||||
virtual status_t closeInput(audio_io_handle_t input) = 0;
|
||||
//
|
||||
|
|
|
@ -169,6 +169,21 @@ protected:
|
|||
DEVICE_CATEGORY_CNT
|
||||
};
|
||||
|
||||
class IOProfile;
|
||||
|
||||
class HwModule {
|
||||
public:
|
||||
HwModule(const char *name);
|
||||
~HwModule();
|
||||
|
||||
void dump(int fd);
|
||||
|
||||
const char *const mName; // base name of the audio HW module (primary, a2dp ...)
|
||||
audio_module_handle_t mHandle;
|
||||
Vector <IOProfile *> mOutputProfiles; // output profiles exposed by this module
|
||||
Vector <IOProfile *> mInputProfiles; // input profiles exposed by this module
|
||||
};
|
||||
|
||||
// the IOProfile class describes the capabilities of an output or input stream.
|
||||
// It is currently assumed that all combination of listed parameters are supported.
|
||||
// It is used by the policy manager to determine if an output or input is suitable for
|
||||
|
@ -176,10 +191,16 @@ protected:
|
|||
// to/from it.
|
||||
class IOProfile
|
||||
{
|
||||
public:
|
||||
IOProfile(const char *module);
|
||||
public:
|
||||
IOProfile(HwModule *module);
|
||||
~IOProfile();
|
||||
|
||||
bool isCompatibleProfile(audio_devices_t device,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channelMask,
|
||||
audio_policy_output_flags_t flags) const;
|
||||
|
||||
void dump(int fd);
|
||||
|
||||
Vector <uint32_t> mSamplingRates; // supported sampling rates
|
||||
|
@ -189,8 +210,7 @@ protected:
|
|||
// routed to)
|
||||
audio_policy_output_flags_t mFlags; // attribute flags (e.g primary output,
|
||||
// direct output...). For outputs only.
|
||||
char *mModuleName; // base name of the audio HW module exposing this I/O stream
|
||||
// (primary, a2dp ...)
|
||||
HwModule *mModule; // audio HW module exposing this I/O stream
|
||||
};
|
||||
|
||||
// default volume curve
|
||||
|
@ -225,10 +245,10 @@ protected:
|
|||
|
||||
audio_io_handle_t mId; // output handle
|
||||
uint32_t mSamplingRate; //
|
||||
uint32_t mFormat; //
|
||||
uint32_t mChannels; // output configuration
|
||||
audio_format_t mFormat; //
|
||||
audio_channel_mask_t mChannelMask; // output configuration
|
||||
uint32_t mLatency; //
|
||||
AudioSystem::output_flags mFlags; //
|
||||
audio_policy_output_flags_t mFlags; //
|
||||
audio_devices_t mDevice; // current device this output is routed to
|
||||
uint32_t mRefCount[AudioSystem::NUM_STREAM_TYPES]; // number of streams of each type using this output
|
||||
nsecs_t mStopTime[AudioSystem::NUM_STREAM_TYPES];
|
||||
|
@ -251,9 +271,8 @@ protected:
|
|||
status_t dump(int fd);
|
||||
|
||||
uint32_t mSamplingRate; //
|
||||
uint32_t mFormat; // input configuration
|
||||
uint32_t mChannels; //
|
||||
AudioSystem::audio_in_acoustics mAcoustics; //
|
||||
audio_format_t mFormat; // input configuration
|
||||
audio_channel_mask_t mChannelMask; //
|
||||
audio_devices_t mDevice; // current device this input is routed to
|
||||
uint32_t mRefCount; // number of AudioRecord clients using this output
|
||||
int mInputSource; // input source selected by application (mediarecorder.h)
|
||||
|
@ -395,12 +414,12 @@ protected:
|
|||
// true if current platform requires a specific output to be opened for this particular
|
||||
// set of parameters. This function is called by getOutput() and is implemented by platform
|
||||
// specific audio policy manager.
|
||||
virtual bool needsDirectOuput(AudioSystem::stream_type stream,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channels,
|
||||
AudioSystem::output_flags flags,
|
||||
uint32_t device);
|
||||
virtual bool needsDirectOuput(audio_stream_type_t stream,
|
||||
uint32_t samplingRate,
|
||||
audio_format_t format,
|
||||
audio_channel_mask_t channelMask,
|
||||
audio_policy_output_flags_t flags,
|
||||
audio_devices_t device);
|
||||
|
||||
virtual uint32_t getMaxEffectsCpuLoad();
|
||||
virtual uint32_t getMaxEffectsMemory();
|
||||
|
@ -431,7 +450,11 @@ protected:
|
|||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channelMask);
|
||||
|
||||
audio_module_handle_t getModuleForDirectoutput(audio_devices_t device,
|
||||
uint32_t samplingRate,
|
||||
uint32_t format,
|
||||
uint32_t channelMask,
|
||||
audio_policy_output_flags_t flags);
|
||||
//
|
||||
// Audio policy configuration file parsing (audio_policy.conf)
|
||||
//
|
||||
|
@ -444,8 +467,8 @@ protected:
|
|||
void loadFormats(char *name, IOProfile *profile);
|
||||
void loadOutChannels(char *name, IOProfile *profile);
|
||||
void loadInChannels(char *name, IOProfile *profile);
|
||||
status_t loadOutput(cnode *root, const char *module);
|
||||
status_t loadInput(cnode *root, const char *module);
|
||||
status_t loadOutput(cnode *root, HwModule *module);
|
||||
status_t loadInput(cnode *root, HwModule *module);
|
||||
void loadHwModule(cnode *root);
|
||||
void loadHwModules(cnode *root);
|
||||
void loadGlobalConfig(cnode *root);
|
||||
|
@ -481,6 +504,7 @@ protected:
|
|||
audio_devices_t mDefaultOutputDevice; // output device selected by default at boot time
|
||||
// (must be in mAttachedOutputDevices)
|
||||
|
||||
Vector <HwModule *> mHwModules;
|
||||
Vector <IOProfile *> mOutputProfiles; // output profiles loaded from audio_policy.conf
|
||||
Vector <IOProfile *> mInputProfiles; // input profiles loaded from audio_policy.conf
|
||||
|
||||
|
|
Loading…
Reference in a new issue