diff options
Diffstat (limited to 'services/audiopolicy')
11 files changed, 134 insertions, 33 deletions
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk index 8728ff3..8c6a53c 100644 --- a/services/audiopolicy/common/managerdefinitions/Android.mk +++ b/services/audiopolicy/common/managerdefinitions/Android.mk @@ -31,6 +31,27 @@ LOCAL_C_INCLUDES += \ LOCAL_EXPORT_C_INCLUDE_DIRS := \ $(LOCAL_PATH)/include +ifeq ($(call is-vendor-board-platform,QCOM),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FLAC_OFFLOAD)),true) +LOCAL_CFLAGS += -DFLAC_OFFLOAD_ENABLED +endif +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true) +LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED +endif +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_WMA_OFFLOAD)),true) +LOCAL_CFLAGS += -DWMA_OFFLOAD_ENABLED +endif +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_ALAC_OFFLOAD)),true) +LOCAL_CFLAGS += -DALAC_OFFLOAD_ENABLED +endif +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_APE_OFFLOAD)),true) +LOCAL_CFLAGS += -DAPE_OFFLOAD_ENABLED +endif +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_AAC_ADTS_OFFLOAD)),true) +LOCAL_CFLAGS += -DAAC_ADTS_OFFLOAD_ENABLED +endif +endif + LOCAL_MODULE := libaudiopolicycomponents include $(BUILD_STATIC_LIBRARY) diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h index 50f622d..e1c2999 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h @@ -72,6 +72,7 @@ public: sp<AudioPort> mPort; audio_devices_t mDevice; // current device this output is routed to audio_patch_handle_t mPatchHandle; + audio_io_handle_t mIoHandle; // output handle uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output nsecs_t mStopTime[AUDIO_STREAM_CNT]; float mCurVolume[AUDIO_STREAM_CNT]; // current stream volume in dB @@ -116,7 +117,6 @@ public: virtual void toAudioPort(struct audio_port *port) const; const sp<IOProfile> mProfile; // I/O profile this output derives from - audio_io_handle_t mIoHandle; // output handle uint32_t mLatency; // audio_output_flags_t mFlags; // AudioMix *mPolicyMix; // non NULL when used by a dynamic policy diff --git a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h index 78d2cdf..4a394bb 100644 --- a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h +++ b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h @@ -74,6 +74,9 @@ const StringToEnum sDeviceTypeToEnumTable[] = { STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM), STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE), STRING_TO_ENUM(AUDIO_DEVICE_OUT_IP), +#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED + STRING_TO_ENUM(AUDIO_DEVICE_OUT_PROXY), +#endif STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT), STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC), STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET), @@ -153,6 +156,7 @@ const StringToEnum sDeviceNameToEnumTable[] = { const StringToEnum sOutputFlagNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT), + STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT_PCM), STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY), STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST), STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER), @@ -198,6 +202,33 @@ const StringToEnum sFormatNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_FORMAT_E_AC3), STRING_TO_ENUM(AUDIO_FORMAT_DTS), STRING_TO_ENUM(AUDIO_FORMAT_DTS_HD), +#ifdef FLAC_OFFLOAD_ENABLED + STRING_TO_ENUM(AUDIO_FORMAT_FLAC), +#endif +#ifdef WMA_OFFLOAD_ENABLED + STRING_TO_ENUM(AUDIO_FORMAT_WMA), + STRING_TO_ENUM(AUDIO_FORMAT_WMA_PRO), +#endif + STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT_OFFLOAD), + STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_OFFLOAD), +#ifdef ALAC_OFFLOAD_ENABLED + STRING_TO_ENUM(AUDIO_FORMAT_ALAC), +#endif +#ifdef APE_OFFLOAD_ENABLED + STRING_TO_ENUM(AUDIO_FORMAT_APE), +#endif +#ifdef AAC_ADTS_OFFLOAD_ENABLED + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_MAIN), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LC), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_SSR), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LTP), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V1), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_SCALABLE), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_ERLC), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_LD), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_HE_V2), + STRING_TO_ENUM(AUDIO_FORMAT_AAC_ADTS_ELD), +#endif }; const StringToEnum sOutChannelsNameToEnumTable[] = { @@ -206,12 +237,17 @@ const StringToEnum sOutChannelsNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD), STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1), STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_2POINT1), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_SURROUND), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_PENTA), + STRING_TO_ENUM(AUDIO_CHANNEL_OUT_6POINT1), }; const StringToEnum sInChannelsNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), + STRING_TO_ENUM(AUDIO_CHANNEL_IN_5POINT1), }; const StringToEnum sIndexChannelsNameToEnumTable[] = { diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index a278375..5ddeaed 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -33,7 +33,7 @@ namespace android { AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port, AudioPolicyClientInterface *clientInterface) - : mPort(port), mDevice(AUDIO_DEVICE_NONE), + : mPort(port), mDevice(AUDIO_DEVICE_NONE), mIoHandle(0), mPatchHandle(0), mClientInterface(clientInterface), mId(0) { // clear usage count for all stream types @@ -223,7 +223,7 @@ void AudioOutputDescriptor::log(const char* indent) SwAudioOutputDescriptor::SwAudioOutputDescriptor( const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface) : AudioOutputDescriptor(profile, clientInterface), - mProfile(profile), mIoHandle(0), mLatency(0), + mProfile(profile), mLatency(0), mFlags((audio_output_flags_t)0), mPolicyMix(NULL), mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0) { diff --git a/services/audiopolicy/enginedefault/Android.mk b/services/audiopolicy/enginedefault/Android.mk index 8d43b89..de84e96 100755 --- a/services/audiopolicy/enginedefault/Android.mk +++ b/services/audiopolicy/enginedefault/Android.mk @@ -31,6 +31,11 @@ LOCAL_C_INCLUDES := \ $(call include-path-for, bionic) \ $(TOPDIR)frameworks/av/services/audiopolicy/common/include +ifeq ($(call is-vendor-board-platform,QCOM),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true) +LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED +endif +endif LOCAL_MODULE := libaudiopolicyenginedefault LOCAL_MODULE_TAGS := optional diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp index 0686414..8b4a085 100755 --- a/services/audiopolicy/enginedefault/src/Engine.cpp +++ b/services/audiopolicy/enginedefault/src/Engine.cpp @@ -408,9 +408,10 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const if (device) break; device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - if (device) break; } + // Allow voice call on USB ANLG DOCK headset + device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; + if (device) break; device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE; if (device) break; device = mApmObserver->getDefaultOutputDevice()->type(); @@ -450,6 +451,13 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const } break; } + + if (isInCall() && (device == AUDIO_DEVICE_NONE)) { + // when in call, get the device for Phone strategy + device = getDeviceForStrategy(STRATEGY_PHONE); + break; + } + break; case STRATEGY_SONIFICATION: @@ -498,6 +506,13 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const case STRATEGY_REROUTING: case STRATEGY_MEDIA: { uint32_t device2 = AUDIO_DEVICE_NONE; + + if (isInCall() && (device == AUDIO_DEVICE_NONE)) { + // when in call, get the device for Phone strategy + device = getDeviceForStrategy(STRATEGY_PHONE); + break; + } + if (strategy != STRATEGY_SONIFICATION) { // no sonification on remote submix (e.g. WFD) if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { @@ -541,14 +556,23 @@ audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const if (device2 == AUDIO_DEVICE_NONE) { device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; } - if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { + if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE) + && (device2 == AUDIO_DEVICE_NONE)) { // no sonification on aux digital (e.g. HDMI) device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; } if ((device2 == AUDIO_DEVICE_NONE) && - (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { + (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK) + && (strategy != STRATEGY_SONIFICATION)) { device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; } +#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED + if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE) + && (device2 == AUDIO_DEVICE_NONE)) { + // no sonification on WFD sink + device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_PROXY; + } +#endif if (device2 == AUDIO_DEVICE_NONE) { device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; } @@ -671,6 +695,8 @@ audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) cons device = AUDIO_DEVICE_IN_WIRED_HEADSET; } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { device = AUDIO_DEVICE_IN_USB_DEVICE; + } else if (availableDeviceTypes & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) { + device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET; } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { device = AUDIO_DEVICE_IN_BUILTIN_MIC; } diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index 8419ed5..acdd23d 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -351,6 +351,14 @@ void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID); if (output != AUDIO_IO_HANDLE_NONE) { + // close active input (if any) before opening new input + audio_io_handle_t activeInput = mInputs.getActiveInput(); + if (activeInput != 0) { + ALOGV("updateCallRouting() close active input before opening new input"); + sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput); + stopInput(activeInput, activeDesc->mSessions.itemAt(0)); + releaseInput(activeInput, activeDesc->mSessions.itemAt(0)); + } sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output); ALOG_ASSERT(!outputDesc->isDuplicated(), "updateCallRouting() RX device output is duplicated"); @@ -1336,6 +1344,12 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, ALOGW("getInputForAttr() could not find device for source %d", inputSource); return BAD_VALUE; } + // block request to open input on USB during voice call + if((AUDIO_MODE_IN_CALL == mEngine->getPhoneState()) && + (device == AUDIO_DEVICE_IN_USB_DEVICE)) { + ALOGV("getInputForAttr(): blocking the request to open input on USB device"); + return BAD_VALUE; + } if (policyMix != NULL) { address = policyMix->mRegistrationId; if (policyMix->mMixType == MIX_TYPE_RECORDERS) { @@ -1356,20 +1370,6 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr, } else { *inputType = API_INPUT_LEGACY; } - // adapt channel selection to input source - switch (inputSource) { - case AUDIO_SOURCE_VOICE_UPLINK: - channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK; - break; - case AUDIO_SOURCE_VOICE_DOWNLINK: - channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK; - break; - case AUDIO_SOURCE_VOICE_CALL: - channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK; - break; - default: - break; - } if (inputSource == AUDIO_SOURCE_HOTWORD) { ssize_t index = mSoundTriggerSessions.indexOfKey(session); if (index >= 0) { @@ -1773,6 +1773,7 @@ audio_io_handle_t AudioPolicyManager::selectOutputForEffects( audio_io_handle_t outputOffloaded = 0; audio_io_handle_t outputDeepBuffer = 0; + audio_io_handle_t outputDirectPcm = 0; for (size_t i = 0; i < outputs.size(); i++) { sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]); @@ -1780,6 +1781,9 @@ audio_io_handle_t AudioPolicyManager::selectOutputForEffects( if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) { outputOffloaded = outputs[i]; } + if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT_PCM) != 0) { + outputDirectPcm = outputs[i]; + } if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) { outputDeepBuffer = outputs[i]; } @@ -1790,6 +1794,9 @@ audio_io_handle_t AudioPolicyManager::selectOutputForEffects( if (outputOffloaded != 0) { return outputOffloaded; } + if (outputDirectPcm != 0) { + return outputDirectPcm; + } if (outputDeepBuffer != 0) { return outputDeepBuffer; } @@ -3781,7 +3788,7 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy) { audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/); audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/); - SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs); + SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mOutputs); SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs); // also take into account external policy-related changes: add all outputs which are diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index bbdf396..c40a435 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -350,7 +350,7 @@ protected: // handle special cases for sonification strategy while in call: mute streams or replace by // a special tone in the device used for communication - void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange); + virtual void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange); audio_mode_t getPhoneState(); @@ -397,7 +397,7 @@ protected: // must be called every time a condition that affects the device choice for a given output is // changed: connected device, phone state, force use, output start, output stop.. // see getDeviceForStrategy() for the use of fromCache parameter - audio_devices_t getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc, + virtual audio_devices_t getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc, bool fromCache); // updates cache of device used by all strategies (mDeviceForStrategy[]) @@ -484,11 +484,11 @@ protected: // if argument "device" is different from AUDIO_DEVICE_NONE, startSource() will force // the re-evaluation of the output device. - status_t startSource(sp<AudioOutputDescriptor> outputDesc, + virtual status_t startSource(sp<AudioOutputDescriptor> outputDesc, audio_stream_type_t stream, audio_devices_t device, uint32_t *delayMs); - status_t stopSource(sp<AudioOutputDescriptor> outputDesc, + virtual status_t stopSource(sp<AudioOutputDescriptor> outputDesc, audio_stream_type_t stream, bool forceDeviceUpdate); @@ -571,7 +571,7 @@ protected: // Audio Policy Engine Interface. AudioPolicyManagerInterface *mEngine; -private: +protected: // updates device caching and output for streams that can influence the // routing of notifications void handleNotificationRoutingForStream(audio_stream_type_t stream); @@ -586,7 +586,7 @@ private: SortedVector<audio_io_handle_t>& outputs /*out*/); uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; } // internal method to return the output handle for the given device and format - audio_io_handle_t getOutputForDevice( + virtual audio_io_handle_t getOutputForDevice( audio_devices_t device, audio_session_t session, audio_stream_type_t stream, @@ -610,7 +610,7 @@ private: AudioMix **policyMix = NULL); // Called by setDeviceConnectionState(). - status_t setDeviceConnectionStateInt(audio_devices_t device, + virtual status_t setDeviceConnectionStateInt(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address, const char *device_name); diff --git a/services/audiopolicy/service/AudioPolicyEffects.cpp b/services/audiopolicy/service/AudioPolicyEffects.cpp index 282ddeb..e71d7a5 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.cpp +++ b/services/audiopolicy/service/AudioPolicyEffects.cpp @@ -442,6 +442,7 @@ effect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root) size_t curSize = sizeof(effect_param_t); size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int); effect_param_t *fx_param = (effect_param_t *)malloc(totSize); + CHECK(fx_param != NULL); param = config_find(root, PARAM_TAG); value = config_find(root, VALUE_TAG); diff --git a/services/audiopolicy/service/AudioPolicyEffects.h b/services/audiopolicy/service/AudioPolicyEffects.h index 3dec437..3845050 100644 --- a/services/audiopolicy/service/AudioPolicyEffects.h +++ b/services/audiopolicy/service/AudioPolicyEffects.h @@ -27,6 +27,8 @@ #include <utils/Vector.h> #include <utils/SortedVector.h> +#include <media/stagefright/foundation/ADebug.h> + namespace android { // ---------------------------------------------------------------------------- @@ -102,6 +104,7 @@ private: ((origParam->psize + 3) & ~3) + ((origParam->vsize + 3) & ~3); effect_param_t *dupParam = (effect_param_t *) malloc(origSize); + CHECK(dupParam != NULL); memcpy(dupParam, origParam, origSize); // This works because the param buffer allocation is also done by // multiples of 4 bytes originally. In theory we should memcpy only diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp index c77cc45..41dd40c 100644 --- a/services/audiopolicy/service/AudioPolicyService.cpp +++ b/services/audiopolicy/service/AudioPolicyService.cpp @@ -899,10 +899,12 @@ void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& c } else { data2->mKeyValuePairs = param2.toString(); } - command->mTime = command2->mTime; - // force delayMs to non 0 so that code below does not request to wait for - // command status as the command is now delayed - delayMs = 1; + if (!data2->mKeyValuePairs.compare(data->mKeyValuePairs)) { + command->mTime = command2->mTime; + // force delayMs to non 0 so that code below does not request to wait for + // command status as the command is now delayed + delayMs = 1; + } } break; case SET_VOLUME: { |