diff options
-rw-r--r-- | include/media/IAudioFlinger.h | 26 | ||||
-rw-r--r-- | media/libmedia/IAudioFlinger.cpp | 105 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 322 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 46 | ||||
-rw-r--r-- | services/audioflinger/AudioPolicyService.cpp | 80 |
5 files changed, 356 insertions, 223 deletions
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 8239b0e..9e938d1 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -29,6 +29,7 @@ #include <media/IAudioFlingerClient.h> #include <system/audio.h> #include <system/audio_policy.h> +#include <hardware/audio_policy.h> #include <hardware/audio_effect.h> #include <media/IEffect.h> #include <media/IEffectClient.h> @@ -126,23 +127,24 @@ public: // retrieve the audio recording buffer size virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const = 0; - 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) = 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; virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2) = 0; virtual status_t closeOutput(audio_io_handle_t output) = 0; virtual status_t suspendOutput(audio_io_handle_t output) = 0; virtual status_t restoreOutput(audio_io_handle_t output) = 0; - virtual audio_io_handle_t openInput(uint32_t *pDevices, - uint32_t *pSamplingRate, - audio_format_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; virtual status_t closeInput(audio_io_handle_t input) = 0; virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) = 0; @@ -178,6 +180,8 @@ public: virtual status_t moveEffects(int session, audio_io_handle_t srcOutput, audio_io_handle_t dstOutput) = 0; + + virtual audio_module_handle_t loadHwModule(const char *name) = 0; }; diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index ce10c8e..81e259a 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -69,7 +69,8 @@ enum { QUERY_EFFECT, GET_EFFECT_DESCRIPTOR, CREATE_EFFECT, - MOVE_EFFECTS + MOVE_EFFECTS, + LOAD_HW_MODULE }; class BpAudioFlinger : public BpInterface<IAudioFlinger> @@ -355,38 +356,40 @@ public: return reply.readInt32(); } - 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) { Parcel data, reply; - uint32_t devices = pDevices ? *pDevices : 0; + audio_devices_t devices = pDevices ? *pDevices : (audio_devices_t)0; 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 : (audio_channel_mask_t)0; uint32_t latency = pLatencyMs ? *pLatencyMs : 0; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeInt32(module); data.writeInt32(devices); data.writeInt32(samplingRate); data.writeInt32(format); - data.writeInt32(channels); + data.writeInt32(channelMask); data.writeInt32(latency); data.writeInt32((int32_t) flags); remote()->transact(OPEN_OUTPUT, data, &reply); audio_io_handle_t output = (audio_io_handle_t) reply.readInt32(); ALOGV("openOutput() returned output, %d", output); - devices = reply.readInt32(); + devices = (audio_devices_t)reply.readInt32(); if (pDevices) *pDevices = devices; samplingRate = reply.readInt32(); if (pSamplingRate) *pSamplingRate = samplingRate; format = (audio_format_t) reply.readInt32(); if (pFormat) *pFormat = format; - channels = reply.readInt32(); - if (pChannels) *pChannels = channels; + channelMask = (audio_channel_mask_t)reply.readInt32(); + if (pChannelMask) *pChannelMask = channelMask; latency = reply.readInt32(); if (pLatencyMs) *pLatencyMs = latency; return output; @@ -430,34 +433,34 @@ public: return reply.readInt32(); } - 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) { Parcel data, reply; - uint32_t devices = pDevices ? *pDevices : 0; + audio_devices_t devices = pDevices ? *pDevices : (audio_devices_t)0; 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 : (audio_channel_mask_t)0; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeInt32(module); data.writeInt32(devices); data.writeInt32(samplingRate); data.writeInt32(format); - data.writeInt32(channels); - data.writeInt32((int32_t) acoustics); + data.writeInt32(channelMask); remote()->transact(OPEN_INPUT, data, &reply); audio_io_handle_t input = (audio_io_handle_t) reply.readInt32(); - devices = reply.readInt32(); + devices = (audio_devices_t)reply.readInt32(); if (pDevices) *pDevices = devices; samplingRate = reply.readInt32(); if (pSamplingRate) *pSamplingRate = samplingRate; format = (audio_format_t) reply.readInt32(); if (pFormat) *pFormat = format; - channels = reply.readInt32(); - if (pChannels) *pChannels = channels; + channelMask = (audio_channel_mask_t)reply.readInt32(); + if (pChannelMask) *pChannelMask = channelMask; return input; } @@ -668,6 +671,15 @@ public: remote()->transact(MOVE_EFFECTS, data, &reply); return reply.readInt32(); } + + virtual audio_module_handle_t loadHwModule(const char *name) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); + data.writeCString(name); + remote()->transact(LOAD_HW_MODULE, data, &reply); + return (audio_module_handle_t) reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger"); @@ -837,24 +849,26 @@ status_t BnAudioFlinger::onTransact( } break; case OPEN_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t devices = data.readInt32(); + audio_module_handle_t module = (audio_module_handle_t)data.readInt32(); + audio_devices_t devices = (audio_devices_t)data.readInt32(); uint32_t samplingRate = data.readInt32(); audio_format_t format = (audio_format_t) data.readInt32(); - uint32_t channels = data.readInt32(); + audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32(); uint32_t latency = data.readInt32(); audio_policy_output_flags_t flags = (audio_policy_output_flags_t) data.readInt32(); - audio_io_handle_t output = openOutput(&devices, - &samplingRate, - &format, - &channels, - &latency, - flags); + audio_io_handle_t output = openOutput(module, + &devices, + &samplingRate, + &format, + &channelMask, + &latency, + flags); ALOGV("OPEN_OUTPUT output, %p", output); reply->writeInt32((int32_t) output); reply->writeInt32(devices); reply->writeInt32(samplingRate); reply->writeInt32(format); - reply->writeInt32(channels); + reply->writeInt32(channelMask); reply->writeInt32(latency); return NO_ERROR; } break; @@ -882,22 +896,22 @@ status_t BnAudioFlinger::onTransact( } break; case OPEN_INPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - uint32_t devices = data.readInt32(); + audio_module_handle_t module = (audio_module_handle_t)data.readInt32(); + audio_devices_t devices = (audio_devices_t)data.readInt32(); uint32_t samplingRate = data.readInt32(); audio_format_t format = (audio_format_t) data.readInt32(); - uint32_t channels = data.readInt32(); - audio_in_acoustics_t acoustics = (audio_in_acoustics_t) data.readInt32(); + audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32(); - audio_io_handle_t input = openInput(&devices, - &samplingRate, - &format, - &channels, - acoustics); + audio_io_handle_t input = openInput(module, + &devices, + &samplingRate, + &format, + &channelMask); reply->writeInt32((int32_t) input); reply->writeInt32(devices); reply->writeInt32(samplingRate); reply->writeInt32(format); - reply->writeInt32(channels); + reply->writeInt32(channelMask); return NO_ERROR; } break; case CLOSE_INPUT: { @@ -1015,6 +1029,11 @@ status_t BnAudioFlinger::onTransact( reply->writeInt32(moveEffects(session, srcOutput, dstOutput)); return NO_ERROR; } break; + case LOAD_HW_MODULE: { + CHECK_INTERFACE(IAudioFlinger, data, reply); + reply->writeInt32(loadHwModule(data.readCString())); + return NO_ERROR; + } break; default: return BBinder::onTransact(code, data, reply, flags); } 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<String16>& 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 <system/audio.h> #include <hardware/audio.h> +#include <hardware/audio_policy.h> #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<Client> > 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<audio_hw_device_t*> mAudioHwDevs; + DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*> 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<SyncEvent> > 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<IAudioFlinger> 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<IAudioFlinger> 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<IAudioFlinger> 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<IAudioFlinger> 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<IAudioFlinger> 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 <unnamed> |