From: Colin Cross Date: Tue, 18 Jun 2013 01:21:38 +0000 (-0700) Subject: am 2769ce79: Merge "Use accessor to read property serial numbers" X-Git-Tag: android-x86-4.4-r1~21^2~1 X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fhardware-libhardware_legacy.git;a=commitdiff_plain;h=248c9aa92c8f3e2f33a0e8a02436ea366266495f;hp=2769ce79def80023e454708deec176e3259dc586 am 2769ce79: Merge "Use accessor to read property serial numbers" * commit '2769ce79def80023e454708deec176e3259dc586': Use accessor to read property serial numbers --- diff --git a/Android.mk b/Android.mk index 1faf6e2..1050811 100644 --- a/Android.mk +++ b/Android.mk @@ -9,7 +9,7 @@ LEGACY_AUDIO_MAKEFILES := $(call all-named-subdir-makefiles,audio) LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -LOCAL_SHARED_LIBRARIES := libcutils libwpa_client +LOCAL_SHARED_LIBRARIES := libcutils liblog libwpa_client LOCAL_INCLUDES += $(LOCAL_PATH) diff --git a/audio/Android.mk b/audio/Android.mk index a69b9cd..f061663 100644 --- a/audio/Android.mk +++ b/audio/Android.mk @@ -42,7 +42,8 @@ LOCAL_SRC_FILES := \ LOCAL_SHARED_LIBRARIES := \ libcutils \ - libutils + libutils \ + liblog LOCAL_STATIC_LIBRARIES := \ libmedia_helper diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index 134fb3b..236bf69 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -27,6 +27,9 @@ // A device mask for all audio input devices that are considered "virtual" when evaluating // active inputs in getActiveInput() #define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX +// A device mask for all audio output devices that are considered "remote" when evaluating +// active output devices in isStreamActiveRemotely() +#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX #include #include @@ -332,31 +335,29 @@ void AudioPolicyManagerBase::setPhoneState(int state) newDevice = hwOutputDesc->device(); } - // when changing from ring tone to in call mode, mute the ringing tone - // immediately and delay the route change to avoid sending the ring tone - // tail into the earpiece or headset. int delayMs = 0; - if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) { - // delay the device change command by twice the output latency to have some margin - // and be sure that audio buffers not yet affected by the mute are out when - // we actually apply the route change - delayMs = hwOutputDesc->mLatency*2; - setStreamMute(AudioSystem::RING, true, mPrimaryOutput); - } - if (isStateInCall(state)) { + nsecs_t sysTime = systemTime(); for (size_t i = 0; i < mOutputs.size(); i++) { AudioOutputDescriptor *desc = mOutputs.valueAt(i); - //take the biggest latency for all outputs - if (delayMs < (int)desc->mLatency*2) { + // mute media and sonification strategies and delay device switch by the largest + // latency of any output where either strategy is active. + // This avoid sending the ring tone or music tail into the earpiece or headset. + if ((desc->isStrategyActive(STRATEGY_MEDIA, + SONIFICATION_HEADSET_MUSIC_DELAY, + sysTime) || + desc->isStrategyActive(STRATEGY_SONIFICATION, + SONIFICATION_HEADSET_MUSIC_DELAY, + sysTime)) && + (delayMs < (int)desc->mLatency*2)) { delayMs = desc->mLatency*2; } - //mute STRATEGY_MEDIA on all outputs - if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) { - setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); - setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, - getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); - } + setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i)); + setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS, + getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/)); + setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i)); + setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS, + getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/)); } } @@ -367,11 +368,6 @@ void AudioPolicyManagerBase::setPhoneState(int state) // pertaining to sonification strategy see handleIncallSonification() if (isStateInCall(state)) { ALOGV("setPhoneState() in call state management: new state is %d", state); - // unmute the ringing tone after a sufficient delay if it was muted before - // setting output device above - if (oldState == AudioSystem::MODE_RINGTONE) { - setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS); - } for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { handleIncallSonification(stream, true, true); } @@ -560,10 +556,27 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str channelMask, (audio_output_flags_t)flags); if (profile != NULL) { + AudioOutputDescriptor *outputDesc = NULL; - ALOGV("getOutput() opening direct output device %x", device); - - AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(profile); + for (size_t i = 0; i < mOutputs.size(); i++) { + AudioOutputDescriptor *desc = mOutputs.valueAt(i); + if (!desc->isDuplicated() && (profile == desc->mProfile)) { + outputDesc = desc; + // reuse direct output if currently open and configured with same parameters + if ((samplingRate == outputDesc->mSamplingRate) && + (format == outputDesc->mFormat) && + (channelMask == outputDesc->mChannelMask)) { + outputDesc->mDirectOpenCount++; + ALOGV("getOutput() reusing direct output %d", output); + return mOutputs.keyAt(i); + } + } + } + // close direct output if currently open and configured with different parameters + if (outputDesc != NULL) { + closeOutput(outputDesc->mId); + } + outputDesc = new AudioOutputDescriptor(profile); outputDesc->mDevice = device; outputDesc->mSamplingRate = samplingRate; outputDesc->mFormat = (audio_format_t)format; @@ -572,6 +585,7 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str outputDesc->mFlags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);; outputDesc->mRefCount[stream] = 0; outputDesc->mStopTime[stream] = 0; + outputDesc->mDirectOpenCount = 1; output = mpClientInterface->openOutput(profile->mModule->mHandle, &outputDesc->mDevice, &outputDesc->mSamplingRate, @@ -596,7 +610,8 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str return 0; } addOutput(output, outputDesc); - ALOGV("getOutput() returns direct output %d", output); + mPreviousOutputs = mOutputs; + ALOGV("getOutput() returns new direct output %d", output); return output; } @@ -770,7 +785,7 @@ status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, audio_io_handle_t curOutput = mOutputs.keyAt(i); AudioOutputDescriptor *desc = mOutputs.valueAt(i); if (curOutput != output && - desc->refCount() != 0 && + desc->isActive() && outputDesc->sharesHwModuleWith(desc) && newDevice != desc->device()) { setOutputDevice(curOutput, @@ -802,7 +817,7 @@ void AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) int testIndex = testOutputIndex(output); if (testIndex != 0) { AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index); - if (outputDesc->refCount() == 0) { + if (outputDesc->isActive()) { mpClientInterface->closeOutput(output); delete mOutputs.valueAt(index); mOutputs.removeItem(output); @@ -812,11 +827,16 @@ void AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output) } #endif //AUDIO_POLICY_TEST - if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { - mpClientInterface->closeOutput(output); - delete mOutputs.valueAt(index); - mOutputs.removeItem(output); - mPreviousOutputs = mOutputs; + AudioOutputDescriptor *desc = mOutputs.valueAt(index); + if (desc->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) { + if (desc->mDirectOpenCount <= 0) { + ALOGW("releaseOutput() invalid open count %d for output %d", + desc->mDirectOpenCount, output); + return; + } + if (--desc->mDirectOpenCount == 0) { + closeOutput(output); + } } } @@ -921,6 +941,10 @@ status_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) } } + audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource); + if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) { + inputDesc->mDevice = newDevice; + } AudioParameter param = AudioParameter(); param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice); @@ -1170,8 +1194,21 @@ bool AudioPolicyManagerBase::isStreamActive(int stream, uint32_t inPastMs) const { nsecs_t sysTime = systemTime(); for (size_t i = 0; i < mOutputs.size(); i++) { - if (mOutputs.valueAt(i)->mRefCount[stream] != 0 || - ns2ms(sysTime - mOutputs.valueAt(i)->mStopTime[stream]) < inPastMs) { + const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); + if (outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { + return true; + } + } + return false; +} + +bool AudioPolicyManagerBase::isStreamActiveRemotely(int stream, uint32_t inPastMs) const +{ + nsecs_t sysTime = systemTime(); + for (size_t i = 0; i < mOutputs.size(); i++) { + const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i); + if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && + outputDesc->isStreamActive((AudioSystem::stream_type)stream, inPastMs, sysTime)) { return true; } } @@ -1813,8 +1850,9 @@ void AudioPolicyManagerBase::closeOutput(audio_io_handle_t output) mpClientInterface->setParameters(output, param.toString()); mpClientInterface->closeOutput(output); - delete mOutputs.valueFor(output); + delete outputDesc; mOutputs.removeItem(output); + mPreviousOutputs = mOutputs; } SortedVector AudioPolicyManagerBase::getOutputsForDevice(audio_devices_t device, @@ -1861,7 +1899,7 @@ void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy) // mute strategy while moving tracks from one output to another for (size_t i = 0; i < srcOutputs.size(); i++) { AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]); - if (desc->strategyRefCount(strategy) != 0) { + if (desc->isStrategyActive(strategy)) { setStrategyMute(strategy, true, srcOutputs[i]); setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice); } @@ -1992,18 +2030,18 @@ audio_devices_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, b // use device for strategy media // 6: the strategy DTMF is active on the output: // use device for strategy DTMF - if (outputDesc->isUsedByStrategy(STRATEGY_ENFORCED_AUDIBLE)) { + if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) { device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache); } else if (isInCall() || - outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { + outputDesc->isStrategyActive(STRATEGY_PHONE)) { device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); - } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { + } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); - } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION_RESPECTFUL)) { + } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache); - } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) { + } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) { device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); - } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) { + } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) { device = getDeviceForStrategy(STRATEGY_DTMF, fromCache); } @@ -2083,6 +2121,13 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy st case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall()) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); + } else if (isStreamActiveRemotely(AudioSystem::MUSIC, + SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { + // while media is playing on a remote device, use the the sonification behavior. + // Note that we test this usecase before testing if media is playing because + // the isStreamActive() method only informs about the activity of a stream, not + // if it's for local playback. Note also that we use the same delay between both tests + device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/); } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { // while media is playing (or has recently played), use the same device device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/); @@ -2293,11 +2338,10 @@ uint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor uint32_t muteWaitMs = 0; audio_devices_t device = outputDesc->device(); - bool shouldMute = (outputDesc->refCount() != 0) && - (AudioSystem::popCount(device) >= 2); + bool shouldMute = outputDesc->isActive() && (AudioSystem::popCount(device) >= 2); // temporary mute output if device selection changes to avoid volume bursts due to // different per device volumes - bool tempMute = (outputDesc->refCount() != 0) && (device != prevDevice); + bool tempMute = outputDesc->isActive() && (device != prevDevice); for (size_t i = 0; i < NUM_STRATEGIES; i++) { audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/); @@ -2314,6 +2358,7 @@ uint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor if (doMute || tempMute) { for (size_t j = 0; j < mOutputs.size(); j++) { AudioOutputDescriptor *desc = mOutputs.valueAt(j); + // skip output if it does not share any device with current output if ((desc->supportedDevices() & outputDesc->supportedDevices()) == AUDIO_DEVICE_NONE) { continue; @@ -2322,13 +2367,14 @@ uint32_t AudioPolicyManagerBase::checkDeviceMuteStrategies(AudioOutputDescriptor ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d", mute ? "muting" : "unmuting", i, curDevice, curOutput); setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs); - if (desc->strategyRefCount((routing_strategy)i) != 0) { - if (tempMute) { + if (desc->isStrategyActive((routing_strategy)i)) { + // do tempMute only for current output + if (tempMute && (desc == outputDesc)) { setStrategyMute((routing_strategy)i, true, curOutput); setStrategyMute((routing_strategy)i, false, curOutput, desc->latency() * 2, device); } - if (tempMute || mute) { + if ((tempMute && (desc == outputDesc)) || mute) { if (muteWaitMs < desc->latency()) { muteWaitMs = desc->latency(); } @@ -2360,13 +2406,20 @@ uint32_t AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs); AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); AudioParameter param; - uint32_t muteWaitMs = 0; + uint32_t muteWaitMs; if (outputDesc->isDuplicated()) { muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs); muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs); return muteWaitMs; } + // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current + // output profile + if ((device != AUDIO_DEVICE_NONE) && + ((device & outputDesc->mProfile->mSupportedDevices) == 0)) { + return 0; + } + // filter devices according to output selected device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices); @@ -2428,7 +2481,14 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) { uint32_t device = AUDIO_DEVICE_NONE; - switch(inputSource) { + switch (inputSource) { + case AUDIO_SOURCE_VOICE_UPLINK: + if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { + device = AUDIO_DEVICE_IN_VOICE_CALL; + break; + } + // FALL THROUGH + case AUDIO_SOURCE_DEFAULT: case AUDIO_SOURCE_MIC: case AUDIO_SOURCE_VOICE_RECOGNITION: @@ -2449,7 +2509,6 @@ audio_devices_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource) device = AUDIO_DEVICE_IN_BUILTIN_MIC; } break; - case AUDIO_SOURCE_VOICE_UPLINK: case AUDIO_SOURCE_VOICE_DOWNLINK: case AUDIO_SOURCE_VOICE_CALL: if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) { @@ -2971,7 +3030,7 @@ AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( : mId(0), mSamplingRate(0), mFormat((audio_format_t)0), mChannelMask((audio_channel_mask_t)0), mLatency(0), mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), - mOutput1(0), mOutput2(0), mProfile(profile) + mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0) { // clear usage count for all stream types for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { @@ -2991,7 +3050,7 @@ AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor( } } -audio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() +audio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::device() const { if (isDuplicated()) { return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); @@ -3037,26 +3096,6 @@ void AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem:: ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); } -uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount() -{ - uint32_t refcount = 0; - for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { - refcount += mRefCount[i]; - } - return refcount; -} - -uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy) -{ - uint32_t refCount = 0; - for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) { - if (getStrategy((AudioSystem::stream_type)i) == strategy) { - refCount += mRefCount[i]; - } - } - return refCount; -} - audio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices() { if (isDuplicated()) { @@ -3068,16 +3107,46 @@ audio_devices_t AudioPolicyManagerBase::AudioOutputDescriptor::supportedDevices( bool AudioPolicyManagerBase::AudioOutputDescriptor::isActive(uint32_t inPastMs) const { - nsecs_t sysTime = systemTime(); + return isStrategyActive(NUM_STRATEGIES, inPastMs); +} + +bool AudioPolicyManagerBase::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy, + uint32_t inPastMs, + nsecs_t sysTime) const +{ + if ((sysTime == 0) && (inPastMs != 0)) { + sysTime = systemTime(); + } for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { - if (mRefCount[i] != 0 || - ns2ms(sysTime - mStopTime[i]) < inPastMs) { + if (((getStrategy((AudioSystem::stream_type)i) == strategy) || + (NUM_STRATEGIES == strategy)) && + isStreamActive((AudioSystem::stream_type)i, inPastMs, sysTime)) { return true; } } return false; } +bool AudioPolicyManagerBase::AudioOutputDescriptor::isStreamActive(AudioSystem::stream_type stream, + uint32_t inPastMs, + nsecs_t sysTime) const +{ + if (mRefCount[stream] != 0) { + return true; + } + if (inPastMs == 0) { + return false; + } + if (sysTime == 0) { + sysTime = systemTime(); + } + if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { + return true; + } + return false; +} + + status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) { const size_t SIZE = 256; @@ -3406,6 +3475,7 @@ const struct StringToEnum sOutChannelsNameToEnumTable[] = { const struct StringToEnum sInChannelsNameToEnumTable[] = { STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO), STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO), + STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK), }; diff --git a/audio/audio_policy_hal.cpp b/audio/audio_policy_hal.cpp index bff6b74..1604809 100644 --- a/audio/audio_policy_hal.cpp +++ b/audio/audio_policy_hal.cpp @@ -302,6 +302,13 @@ static bool ap_is_stream_active(const struct audio_policy *pol, audio_stream_typ return lap->apm->isStreamActive((int) stream, in_past_ms); } +static bool ap_is_stream_active_remotely(const struct audio_policy *pol, audio_stream_type_t stream, + uint32_t in_past_ms) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->isStreamActiveRemotely((int) stream, in_past_ms); +} + static bool ap_is_source_active(const struct audio_policy *pol, audio_source_t source) { const struct legacy_audio_policy *lap = to_clap(pol); @@ -358,6 +365,7 @@ static int create_legacy_ap(const struct audio_policy_device *device, lap->policy.unregister_effect = ap_unregister_effect; lap->policy.set_effect_enabled = ap_set_effect_enabled; lap->policy.is_stream_active = ap_is_stream_active; + lap->policy.is_stream_active_remotely = ap_is_stream_active_remotely; lap->policy.is_source_active = ap_is_source_active; lap->policy.dump = ap_dump; diff --git a/include/hardware_legacy/AudioPolicyInterface.h b/include/hardware_legacy/AudioPolicyInterface.h index 51f4822..d2dd430 100644 --- a/include/hardware_legacy/AudioPolicyInterface.h +++ b/include/hardware_legacy/AudioPolicyInterface.h @@ -157,6 +157,7 @@ public: virtual status_t setEffectEnabled(int id, bool enabled) = 0; virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0; + virtual bool isStreamActiveRemotely(int stream, uint32_t inPastMs = 0) const = 0; virtual bool isSourceActive(audio_source_t source) const = 0; //dump state diff --git a/include/hardware_legacy/AudioPolicyManagerBase.h b/include/hardware_legacy/AudioPolicyManagerBase.h index b175670..7ba71e7 100644 --- a/include/hardware_legacy/AudioPolicyManagerBase.h +++ b/include/hardware_legacy/AudioPolicyManagerBase.h @@ -133,6 +133,10 @@ public: virtual status_t setEffectEnabled(int id, bool enabled); virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const; + // return whether a stream is playing remotely, override to change the definition of + // local/remote playback, used for instance by notification manager to not make + // media players lose audio focus when not playing locally + virtual bool isStreamActiveRemotely(int stream, uint32_t inPastMs = 0) const; virtual bool isSourceActive(audio_source_t source) const; virtual status_t dump(int fd); @@ -241,16 +245,19 @@ protected: status_t dump(int fd); - audio_devices_t device(); - void changeRefCount(AudioSystem::stream_type, int delta); - uint32_t refCount(); - uint32_t strategyRefCount(routing_strategy strategy); - bool isUsedByStrategy(routing_strategy strategy) { return (strategyRefCount(strategy) != 0);} + audio_devices_t device() const; + void changeRefCount(AudioSystem::stream_type stream, int delta); bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); } audio_devices_t supportedDevices(); uint32_t latency(); bool sharesHwModuleWith(const AudioOutputDescriptor *outputDesc); - bool isActive(uint32_t inPastMs) const; + bool isActive(uint32_t inPastMs = 0) const; + bool isStreamActive(AudioSystem::stream_type stream, + uint32_t inPastMs = 0, + nsecs_t sysTime = 0) const; + bool isStrategyActive(routing_strategy strategy, + uint32_t inPastMs = 0, + nsecs_t sysTime = 0) const; audio_io_handle_t mId; // output handle uint32_t mSamplingRate; // @@ -268,6 +275,7 @@ protected: const IOProfile *mProfile; // I/O profile this output derives from bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible // device selection. See checkDeviceMuteStrategies() + uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only) }; // descriptor for audio inputs. Used to maintain current configuration of each opened audio input diff --git a/wifi/wifi.c b/wifi/wifi.c index 818c212..01d1d23 100644 --- a/wifi/wifi.c +++ b/wifi/wifi.c @@ -60,6 +60,7 @@ extern char *dhcp_lasterror(); extern void get_dhcp_info(); extern int init_module(void *, unsigned long, const char *); extern int delete_module(const char *, unsigned int); +void wifi_close_sockets(int index); static char primary_iface[PROPERTY_VALUE_MAX]; // TODO: use new ANDROID_SOCKET mechanism, once support for multiple @@ -341,6 +342,7 @@ int update_ctrl_interface(const char *config_file) { char *pbuf; char *sptr; struct stat sb; + int ret; if (stat(config_file, &sb) != 0) return -1; @@ -367,6 +369,8 @@ int update_ctrl_interface(const char *config_file) { } else { strcpy(ifc, CONTROL_IFACE_PATH); } + /* Assume file is invalid to begin with */ + ret = -1; /* * if there is a "ctrl_interface=" entry, re-write it ONLY if it is * NOT a directory. The non-directory value option is an Android add-on @@ -377,33 +381,35 @@ int update_ctrl_interface(const char *config_file) { * The is deemed to be a directory if the "DIR=" form is used or * the value begins with "/". */ - if ((sptr = strstr(pbuf, "ctrl_interface=")) && - (!strstr(pbuf, "ctrl_interface=DIR=")) && - (!strstr(pbuf, "ctrl_interface=/"))) { - char *iptr = sptr + strlen("ctrl_interface="); - int ilen = 0; - int mlen = strlen(ifc); - int nwrite; - if (strncmp(ifc, iptr, mlen) != 0) { - ALOGE("ctrl_interface != %s", ifc); - while (((ilen + (iptr - pbuf)) < nread) && (iptr[ilen] != '\n')) - ilen++; - mlen = ((ilen >= mlen) ? ilen : mlen) + 1; - memmove(iptr + mlen, iptr + ilen + 1, nread - (iptr + ilen + 1 - pbuf)); - memset(iptr, '\n', mlen); - memcpy(iptr, ifc, strlen(ifc)); - destfd = TEMP_FAILURE_RETRY(open(config_file, O_RDWR, 0660)); - if (destfd < 0) { - ALOGE("Cannot update \"%s\": %s", config_file, strerror(errno)); - free(pbuf); - return -1; + if (sptr = strstr(pbuf, "ctrl_interface=")) { + ret = 0; + if ((!strstr(pbuf, "ctrl_interface=DIR=")) && + (!strstr(pbuf, "ctrl_interface=/"))) { + char *iptr = sptr + strlen("ctrl_interface="); + int ilen = 0; + int mlen = strlen(ifc); + int nwrite; + if (strncmp(ifc, iptr, mlen) != 0) { + ALOGE("ctrl_interface != %s", ifc); + while (((ilen + (iptr - pbuf)) < nread) && (iptr[ilen] != '\n')) + ilen++; + mlen = ((ilen >= mlen) ? ilen : mlen) + 1; + memmove(iptr + mlen, iptr + ilen + 1, nread - (iptr + ilen + 1 - pbuf)); + memset(iptr, '\n', mlen); + memcpy(iptr, ifc, strlen(ifc)); + destfd = TEMP_FAILURE_RETRY(open(config_file, O_RDWR, 0660)); + if (destfd < 0) { + ALOGE("Cannot update \"%s\": %s", config_file, strerror(errno)); + free(pbuf); + return -1; + } + TEMP_FAILURE_RETRY(write(destfd, pbuf, nread + mlen - ilen -1)); + close(destfd); } - TEMP_FAILURE_RETRY(write(destfd, pbuf, nread + mlen - ilen -1)); - close(destfd); } } free(pbuf); - return 0; + return ret; } int ensure_config_file_exists(const char *config_file) @@ -421,9 +427,13 @@ int ensure_config_file_exists(const char *config_file) ALOGE("Cannot set RW to \"%s\": %s", config_file, strerror(errno)); return -1; } - /* return if filesize is at least 10 bytes */ - if (stat(config_file, &sb) == 0 && sb.st_size > 10) { - return update_ctrl_interface(config_file); + /* return if we were able to update control interface properly */ + if (update_ctrl_interface(config_file) >=0) { + return 0; + } else { + /* This handles the scenario where the file had bad data + * for some reason. We continue and recreate the file. + */ } } else if (errno != ENOENT) { ALOGE("Cannot access \"%s\": %s", config_file, strerror(errno)); @@ -751,11 +761,7 @@ int wifi_ctrl_recv(int index, char *reply, size_t *reply_len) int wifi_wait_on_socket(int index, char *buf, size_t buflen) { size_t nread = buflen - 1; - int fd; - fd_set rfds; int result; - struct timeval tval; - struct timeval *tptr; if (monitor_conn[index] == NULL) { ALOGD("Connection closed\n");