From a4c5a550e2a3bc237179b8684e51718e05894492 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 29 Mar 2012 10:12:40 -0700 Subject: audio policy: load audio hw modules. Audio HW modules are now loaded upon request from audio policy manager according to the configuration in audio_policy.conf. Removed hard coded HW module loading by AudioFlinger at init time. Added methods to IAudioFlinger and AudioPolicyInterface to control the loading of audio HW modules. Added methods to open an output or input stream on a specific hw module. Change-Id: I361b294ece1a9b56b2fb39cc64259dbb73b804f4 --- services/audioflinger/AudioFlinger.cpp | 322 +++++++++++++++------------ services/audioflinger/AudioFlinger.h | 46 ++-- services/audioflinger/AudioPolicyService.cpp | 80 +++++-- 3 files changed, 279 insertions(+), 169 deletions(-) (limited to 'services') diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index e926292..9e6a6df 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -149,13 +149,6 @@ out: return rc; } -static const char * const audio_interfaces[] = { - AUDIO_HARDWARE_MODULE_ID_PRIMARY, - AUDIO_HARDWARE_MODULE_ID_A2DP, - AUDIO_HARDWARE_MODULE_ID_USB, -}; -#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0]))) - // ---------------------------------------------------------------------------- AudioFlinger::AudioFlinger() @@ -191,87 +184,9 @@ void AudioFlinger::onFirstRef() } } - for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) { - const hw_module_t *mod; - audio_hw_device_t *dev; - - rc = load_audio_interface(audio_interfaces[i], &mod, &dev); - if (rc) - continue; - - ALOGI("Loaded %s audio interface from %s (%s)", audio_interfaces[i], - mod->name, mod->id); - mAudioHwDevs.push(dev); - - if (mPrimaryHardwareDev == NULL) { - mPrimaryHardwareDev = dev; - ALOGI("Using '%s' (%s.%s) as the primary audio interface", - mod->name, mod->id, audio_interfaces[i]); - } - } - - if (mPrimaryHardwareDev == NULL) { - ALOGE("Primary audio interface not found"); - // proceed, all later accesses to mPrimaryHardwareDev verify it's safe with initCheck() - } - - // Currently (mPrimaryHardwareDev == NULL) == (mAudioHwDevs.size() == 0), but the way the - // primary HW dev is selected can change so these conditions might not always be equivalent. - // When that happens, re-visit all the code that assumes this. - - AutoMutex lock(mHardwareLock); - - // Determine the level of master volume support the primary audio HAL has, - // and set the initial master volume at the same time. - float initialVolume = 1.0; - mMasterVolumeSupportLvl = MVS_NONE; - if (0 == mPrimaryHardwareDev->init_check(mPrimaryHardwareDev)) { - audio_hw_device_t *dev = mPrimaryHardwareDev; - - mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME; - if ((NULL != dev->get_master_volume) && - (NO_ERROR == dev->get_master_volume(dev, &initialVolume))) { - mMasterVolumeSupportLvl = MVS_FULL; - } else { - mMasterVolumeSupportLvl = MVS_SETONLY; - initialVolume = 1.0; - } - - mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; - if ((NULL == dev->set_master_volume) || - (NO_ERROR != dev->set_master_volume(dev, initialVolume))) { - mMasterVolumeSupportLvl = MVS_NONE; - } - mHardwareStatus = AUDIO_HW_IDLE; - } - - // Set the mode for each audio HAL, and try to set the initial volume (if - // supported) for all of the non-primary audio HALs. - for (size_t i = 0; i < mAudioHwDevs.size(); i++) { - audio_hw_device_t *dev = mAudioHwDevs[i]; - - mHardwareStatus = AUDIO_HW_INIT; - rc = dev->init_check(dev); - mHardwareStatus = AUDIO_HW_IDLE; - if (rc == 0) { - mMode = AUDIO_MODE_NORMAL; // assigned multiple times with same value - mHardwareStatus = AUDIO_HW_SET_MODE; - dev->set_mode(dev, mMode); - - if ((dev != mPrimaryHardwareDev) && - (NULL != dev->set_master_volume)) { - mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; - dev->set_master_volume(dev, initialVolume); - } - - mHardwareStatus = AUDIO_HW_IDLE; - } - } - - mMasterVolumeSW = (MVS_NONE == mMasterVolumeSupportLvl) - ? initialVolume - : 1.0; - mMasterVolume = initialVolume; + mMode = AUDIO_MODE_NORMAL; + mMasterVolumeSW = 1.0; + mMasterVolume = 1.0; mHardwareStatus = AUDIO_HW_IDLE; } @@ -289,18 +204,41 @@ AudioFlinger::~AudioFlinger() for (size_t i = 0; i < mAudioHwDevs.size(); i++) { // no mHardwareLock needed, as there are no other references to this - audio_hw_device_close(mAudioHwDevs[i]); + audio_hw_device_close(mAudioHwDevs.valueAt(i)->hwDevice()); + delete mAudioHwDevs.valueAt(i); } } -audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(uint32_t devices) +static const char * const audio_interfaces[] = { + AUDIO_HARDWARE_MODULE_ID_PRIMARY, + AUDIO_HARDWARE_MODULE_ID_A2DP, + AUDIO_HARDWARE_MODULE_ID_USB, +}; +#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0]))) + +audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(audio_module_handle_t module, uint32_t devices) { - /* first matching HW device is returned */ + // if module is 0, the request comes from an old policy manager and we should load + // well known modules + if (module == 0) { + ALOGW("findSuitableHwDev_l() loading well know audio hw modules"); + for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) { + loadHwModule_l(audio_interfaces[i]); + } + } else { + // check a match for the requested module handle + AudioHwDevice *audioHwdevice = mAudioHwDevs.valueFor(module); + if (audioHwdevice != NULL) { + return audioHwdevice->hwDevice(); + } + } + // then try to find a module supporting the requested device. for (size_t i = 0; i < mAudioHwDevs.size(); i++) { - audio_hw_device_t *dev = mAudioHwDevs[i]; + audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice(); if ((dev->get_supported_devices(dev) & devices) == devices) return dev; } + return NULL; } @@ -411,7 +349,7 @@ status_t AudioFlinger::dump(int fd, const Vector& args) // dump all hardware devs for (size_t i = 0; i < mAudioHwDevs.size(); i++) { - audio_hw_device_t *dev = mAudioHwDevs[i]; + audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice(); dev->dump(dev, fd); } if (locked) mLock.unlock(); @@ -610,11 +548,13 @@ status_t AudioFlinger::setMasterVolume(float value) float swmv = value; + Mutex::Autolock _l(mLock); + // when hw supports master volume, don't scale in sw mixer if (MVS_NONE != mMasterVolumeSupportLvl) { for (size_t i = 0; i < mAudioHwDevs.size(); i++) { AutoMutex lock(mHardwareLock); - audio_hw_device_t *dev = mAudioHwDevs[i]; + audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice(); mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; if (NULL != dev->set_master_volume) { @@ -626,7 +566,6 @@ status_t AudioFlinger::setMasterVolume(float value) swmv = 1.0; } - Mutex::Autolock _l(mLock); mMasterVolume = value; mMasterVolumeSW = swmv; for (size_t i = 0; i < mPlaybackThreads.size(); i++) @@ -853,22 +792,22 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& // ioHandle == 0 means the parameters are global to the audio hardware interface if (ioHandle == 0) { + Mutex::Autolock _l(mLock); status_t final_result = NO_ERROR; { - AutoMutex lock(mHardwareLock); - mHardwareStatus = AUDIO_HW_SET_PARAMETER; - for (size_t i = 0; i < mAudioHwDevs.size(); i++) { - audio_hw_device_t *dev = mAudioHwDevs[i]; - status_t result = dev->set_parameters(dev, keyValuePairs.string()); - final_result = result ?: final_result; - } - mHardwareStatus = AUDIO_HW_IDLE; + AutoMutex lock(mHardwareLock); + mHardwareStatus = AUDIO_HW_SET_PARAMETER; + for (size_t i = 0; i < mAudioHwDevs.size(); i++) { + audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice(); + status_t result = dev->set_parameters(dev, keyValuePairs.string()); + final_result = result ?: final_result; + } + mHardwareStatus = AUDIO_HW_IDLE; } // disable AEC and NS if the device is a BT SCO headset supporting those pre processings AudioParameter param = AudioParameter(keyValuePairs); String8 value; if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) { - Mutex::Autolock _l(mLock); bool btNrecIsOff = (value == AUDIO_PARAMETER_VALUE_OFF); if (mBtNrecIsOff != btNrecIsOff) { for (size_t i = 0; i < mRecordThreads.size(); i++) { @@ -923,6 +862,8 @@ String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& k // ALOGV("getParameters() io %d, keys %s, tid %d, calling pid %d", // ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid()); + Mutex::Autolock _l(mLock); + if (ioHandle == 0) { String8 out_s8; @@ -931,7 +872,7 @@ String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& k { AutoMutex lock(mHardwareLock); mHardwareStatus = AUDIO_HW_GET_PARAMETER; - audio_hw_device_t *dev = mAudioHwDevs[i]; + audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice(); s = dev->get_parameters(dev, keys.string()); mHardwareStatus = AUDIO_HW_IDLE; } @@ -941,8 +882,6 @@ String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& k return out_s8; } - Mutex::Autolock _l(mLock); - PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle); if (playbackThread != NULL) { return playbackThread->getParameters(keys); @@ -5663,28 +5602,84 @@ audio_stream_t* AudioFlinger::RecordThread::stream() const // ---------------------------------------------------------------------------- -audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - uint32_t *pLatencyMs, - audio_policy_output_flags_t flags) +audio_module_handle_t AudioFlinger::loadHwModule(const char *name) +{ + if (!settingsAllowed()) { + return 0; + } + Mutex::Autolock _l(mLock); + return loadHwModule_l(name); +} + +// loadHwModule_l() must be called with AudioFlinger::mLock held +audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name) +{ + for (size_t i = 0; i < mAudioHwDevs.size(); i++) { + if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) { + ALOGW("loadHwModule() module %s already loaded", name); + return mAudioHwDevs.keyAt(i); + } + } + + const hw_module_t *mod; + audio_hw_device_t *dev; + + int rc = load_audio_interface(name, &mod, &dev); + if (rc) { + ALOGI("loadHwModule() error %d loading module %s ", rc, name); + return 0; + } + + mHardwareStatus = AUDIO_HW_INIT; + rc = dev->init_check(dev); + mHardwareStatus = AUDIO_HW_IDLE; + if (rc) { + ALOGI("loadHwModule() init check error %d for module %s ", rc, name); + return 0; + } + + if ((mMasterVolumeSupportLvl != MVS_NONE) && + (NULL != dev->set_master_volume)) { + AutoMutex lock(mHardwareLock); + mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; + dev->set_master_volume(dev, mMasterVolume); + mHardwareStatus = AUDIO_HW_IDLE; + } + + audio_module_handle_t handle = nextUniqueId(); + mAudioHwDevs.add(handle, new AudioHwDevice(name, dev)); + + ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d", + name, mod->name, mod->id, handle); + + return handle; + +} + +audio_io_handle_t AudioFlinger::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) { status_t status; PlaybackThread *thread = NULL; uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT; - uint32_t channels = pChannels ? *pChannels : 0; + audio_channel_mask_t channelMask = pChannelMask ? *pChannelMask : 0; uint32_t latency = pLatencyMs ? *pLatencyMs : 0; audio_stream_out_t *outStream; audio_hw_device_t *outHwDev; - ALOGV("openOutput(), Device %x, SamplingRate %d, Format %d, Channels %x, flags %x", - pDevices ? *pDevices : 0, - samplingRate, - format, - channels, - flags); + ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %d, Channels %x, flags %x", + module, + pDevices ? *pDevices : 0, + samplingRate, + format, + channelMask, + flags); if (pDevices == NULL || *pDevices == 0) { return 0; @@ -5692,19 +5687,19 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, Mutex::Autolock _l(mLock); - outHwDev = findSuitableHwDev_l(*pDevices); + outHwDev = findSuitableHwDev_l(module, *pDevices); if (outHwDev == NULL) return 0; mHardwareStatus = AUDIO_HW_OUTPUT_OPEN; status = outHwDev->open_output_stream(outHwDev, *pDevices, &format, - &channels, &samplingRate, &outStream); + &channelMask, &samplingRate, &outStream); mHardwareStatus = AUDIO_HW_IDLE; ALOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d", outStream, samplingRate, format, - channels, + channelMask, status); if (outStream != NULL) { @@ -5713,7 +5708,7 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) || (format != AUDIO_FORMAT_PCM_16_BIT) || - (channels != AUDIO_CHANNEL_OUT_STEREO)) { + (channelMask != AUDIO_CHANNEL_OUT_STEREO)) { thread = new DirectOutputThread(this, output, id, *pDevices); ALOGV("openOutput() created direct output: ID %d thread %p", id, thread); } else { @@ -5724,11 +5719,55 @@ audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, if (pSamplingRate != NULL) *pSamplingRate = samplingRate; if (pFormat != NULL) *pFormat = format; - if (pChannels != NULL) *pChannels = channels; + if (pChannelMask != NULL) *pChannelMask = channelMask; if (pLatencyMs != NULL) *pLatencyMs = thread->latency(); // notify client processes of the new output creation thread->audioConfigChanged_l(AudioSystem::OUTPUT_OPENED); + + // the first primary output opened designates the primary hw device + if ((mPrimaryHardwareDev == NULL) && (flags & AUDIO_POLICY_OUTPUT_FLAG_PRIMARY)) { + ALOGI("Using module %d has the primary audio interface", module); + mPrimaryHardwareDev = outHwDev; + + AutoMutex lock(mHardwareLock); + mHardwareStatus = AUDIO_HW_SET_MODE; + outHwDev->set_mode(outHwDev, mMode); + + // Determine the level of master volume support the primary audio HAL has, + // and set the initial master volume at the same time. + float initialVolume = 1.0; + mMasterVolumeSupportLvl = MVS_NONE; + + mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME; + if ((NULL != outHwDev->get_master_volume) && + (NO_ERROR == outHwDev->get_master_volume(outHwDev, &initialVolume))) { + mMasterVolumeSupportLvl = MVS_FULL; + } else { + mMasterVolumeSupportLvl = MVS_SETONLY; + initialVolume = 1.0; + } + + mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; + if ((NULL == outHwDev->set_master_volume) || + (NO_ERROR != outHwDev->set_master_volume(outHwDev, initialVolume))) { + mMasterVolumeSupportLvl = MVS_NONE; + } + // now that we have a primary device, initialize master volume on other devices + for (size_t i = 0; i < mAudioHwDevs.size(); i++) { + audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice(); + + if ((dev != mPrimaryHardwareDev) && + (NULL != dev->set_master_volume)) { + dev->set_master_volume(dev, initialVolume); + } + } + mHardwareStatus = AUDIO_HW_IDLE; + mMasterVolumeSW = (MVS_NONE == mMasterVolumeSupportLvl) + ? initialVolume + : 1.0; + mMasterVolume = initialVolume; + } return id; } @@ -5826,20 +5865,20 @@ status_t AudioFlinger::restoreOutput(audio_io_handle_t output) return NO_ERROR; } -audio_io_handle_t AudioFlinger::openInput(uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - audio_in_acoustics_t acoustics) +audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + uint32_t *pChannelMask) { status_t status; RecordThread *thread = NULL; uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0; audio_format_t format = pFormat ? *pFormat : AUDIO_FORMAT_DEFAULT; - uint32_t channels = pChannels ? *pChannels : 0; + audio_channel_mask_t channelMask = pChannelMask ? *pChannelMask : 0; uint32_t reqSamplingRate = samplingRate; audio_format_t reqFormat = format; - uint32_t reqChannels = channels; + audio_channel_mask_t reqChannels = channelMask; audio_stream_in_t *inStream; audio_hw_device_t *inHwDev; @@ -5849,20 +5888,19 @@ audio_io_handle_t AudioFlinger::openInput(uint32_t *pDevices, Mutex::Autolock _l(mLock); - inHwDev = findSuitableHwDev_l(*pDevices); + inHwDev = findSuitableHwDev_l(module, *pDevices); if (inHwDev == NULL) return 0; status = inHwDev->open_input_stream(inHwDev, *pDevices, &format, - &channels, &samplingRate, - acoustics, + &channelMask, &samplingRate, + (audio_in_acoustics_t)0, &inStream); - ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d", + ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, status %d", inStream, samplingRate, format, - channels, - acoustics, + channelMask, status); // If the input could not be opened with the requested parameters and we can handle the conversion internally, @@ -5871,11 +5909,11 @@ audio_io_handle_t AudioFlinger::openInput(uint32_t *pDevices, if (inStream == NULL && status == BAD_VALUE && reqFormat == format && format == AUDIO_FORMAT_PCM_16_BIT && (samplingRate <= 2 * reqSamplingRate) && - (popcount(channels) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) { + (popcount(channelMask) <= FCC_2) && (popcount(reqChannels) <= FCC_2)) { ALOGV("openInput() reopening with proposed sampling rate and channels"); status = inHwDev->open_input_stream(inHwDev, *pDevices, &format, - &channels, &samplingRate, - acoustics, + &channelMask, &samplingRate, + (audio_in_acoustics_t)0, &inStream); } @@ -5897,7 +5935,7 @@ audio_io_handle_t AudioFlinger::openInput(uint32_t *pDevices, ALOGV("openInput() created record thread: ID %d thread %p", id, thread); if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate; if (pFormat != NULL) *pFormat = format; - if (pChannels != NULL) *pChannels = reqChannels; + if (pChannelMask != NULL) *pChannelMask = reqChannels; input->stream->common.standby(&input->stream->common); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index c47d196..e493a9a 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -43,6 +43,7 @@ #include #include +#include #include "AudioBufferProvider.h" @@ -137,12 +138,13 @@ public: virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const; - virtual audio_io_handle_t openOutput(uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - uint32_t *pLatencyMs, - audio_policy_output_flags_t flags); + 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); virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2); @@ -153,11 +155,11 @@ public: virtual status_t restoreOutput(audio_io_handle_t output); - virtual audio_io_handle_t openInput(uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - audio_in_acoustics_t acoustics); + 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); virtual status_t closeInput(audio_io_handle_t input); @@ -196,6 +198,8 @@ public: virtual status_t moveEffects(int sessionId, audio_io_handle_t srcOutput, audio_io_handle_t dstOutput); + virtual audio_module_handle_t loadHwModule(const char *name); + virtual status_t onTransact( uint32_t code, const Parcel& data, @@ -256,7 +260,7 @@ private: // RefBase virtual void onFirstRef(); - audio_hw_device_t* findSuitableHwDev_l(uint32_t devices); + audio_hw_device_t* findSuitableHwDev_l(audio_module_handle_t module, uint32_t devices); void purgeStaleEffects_l(); // standby delay for MIXER and DUPLICATING playback threads is read from property @@ -1699,15 +1703,30 @@ mutable Mutex mLock; // mutex for process, commands and handl MVS_FULL, }; + class AudioHwDevice { + public: + AudioHwDevice(const char *moduleName, audio_hw_device_t *hwDevice) : + mModuleName(strdup(moduleName)), mHwDevice(hwDevice){} + ~AudioHwDevice() { free((void *)mModuleName); } + + const char *moduleName() const { return mModuleName; } + audio_hw_device_t *hwDevice() const { return mHwDevice; } + private: + const char * const mModuleName; + audio_hw_device_t * const mHwDevice; + }; + mutable Mutex mLock; DefaultKeyedVector< pid_t, wp > mClients; // see ~Client() mutable Mutex mHardwareLock; + // NOTE: If both mLock and mHardwareLock mutexes must be held, + // always take mLock before mHardwareLock // These two fields are immutable after onFirstRef(), so no lock needed to access audio_hw_device_t* mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL - Vector mAudioHwDevs; + DefaultKeyedVector mAudioHwDevs; // for dump, indicates which hardware operation is currently in progress (but not stream ops) enum hardware_call_state { @@ -1757,6 +1776,7 @@ mutable Mutex mLock; // mutex for process, commands and handl float masterVolume_l() const; float masterVolumeSW_l() const { return mMasterVolumeSW; } bool masterMute_l() const { return mMasterMute; } + audio_module_handle_t loadHwModule_l(const char *name); Vector < sp > mPendingSyncEvents; // sync events awaiting for a session // to be created diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 62ab45d..15f4349 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -1329,13 +1329,27 @@ status_t AudioPolicyService::loadPreProcessorConfig(const char *path) /* implementation of the interface to the policy manager */ extern "C" { + +static audio_module_handle_t aps_load_hw_module(void *service, + const char *name) +{ + sp af = AudioSystem::get_audio_flinger(); + if (af == 0) { + ALOGW("%s: could not get AudioFlinger", __func__); + return 0; + } + + return af->loadHwModule(name); +} + +// deprecated: replaced by aps_open_output_on_module() static audio_io_handle_t aps_open_output(void *service, - uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - uint32_t *pLatencyMs, - audio_policy_output_flags_t flags) + 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) { sp af = AudioSystem::get_audio_flinger(); if (af == 0) { @@ -1343,7 +1357,26 @@ static audio_io_handle_t aps_open_output(void *service, return 0; } - return af->openOutput(pDevices, pSamplingRate, pFormat, pChannels, + return af->openOutput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask, + pLatencyMs, flags); +} + +static audio_io_handle_t aps_open_output_on_module(void *service, + 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) +{ + sp af = AudioSystem::get_audio_flinger(); + if (af == 0) { + ALOGW("%s: could not get AudioFlinger", __func__); + return 0; + } + ALOGW("%s: %d", __func__, module); + return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask, pLatencyMs, flags); } @@ -1390,12 +1423,29 @@ static int aps_restore_output(void *service, audio_io_handle_t output) return af->restoreOutput(output); } +// deprecated: replaced by aps_open_input_on_module() static audio_io_handle_t aps_open_input(void *service, - uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - uint32_t *pChannels, - audio_in_acoustics_t acoustics) + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask, + audio_in_acoustics_t acoustics) +{ + sp af = AudioSystem::get_audio_flinger(); + if (af == 0) { + ALOGW("%s: could not get AudioFlinger", __func__); + return 0; + } + + return af->openInput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask); +} + +static audio_io_handle_t aps_open_input_on_module(void *service, + audio_module_handle_t module, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask) { sp af = AudioSystem::get_audio_flinger(); if (af == 0) { @@ -1403,8 +1453,7 @@ static audio_io_handle_t aps_open_input(void *service, return 0; } - return af->openInput(pDevices, pSamplingRate, pFormat, pChannels, - acoustics); + return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask); } static int aps_close_input(void *service, audio_io_handle_t input) @@ -1503,6 +1552,9 @@ namespace { stop_tone : aps_stop_tone, set_voice_volume : aps_set_voice_volume, move_effects : aps_move_effects, + load_hw_module : aps_load_hw_module, + open_output_on_module : aps_open_output_on_module, + open_input_on_module : aps_open_input_on_module, }; }; // namespace -- cgit v1.1