diff options
author | Jonas Larsson <jonas@hallerud.se> | 2010-08-14 22:01:43 +0200 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2010-08-16 17:30:14 -0400 |
commit | 55443cc86fb4bb16ab735fa94132039cf481b9d3 (patch) | |
tree | 29d702225f9875b3db3e3afad0ea7baddaf92565 | |
parent | 76ef08c2c94c7f9e27337cdd18aa0b43f68f6409 (diff) | |
download | frameworks_base-55443cc86fb4bb16ab735fa94132039cf481b9d3.zip frameworks_base-55443cc86fb4bb16ab735fa94132039cf481b9d3.tar.gz frameworks_base-55443cc86fb4bb16ab735fa94132039cf481b9d3.tar.bz2 |
Sound tweaks: Always on speaker 2.0, headphone attenuation, headphone music vol limit, audio focus requests.
-rw-r--r-- | core/java/android/provider/Settings.java | 9 | ||||
-rw-r--r-- | libs/audioflinger/AudioPolicyManagerBase.cpp | 106 | ||||
-rw-r--r-- | services/java/com/android/server/NotificationPlayer.java | 5 |
3 files changed, 106 insertions, 14 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9cd0d3a..d997737 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1499,6 +1499,15 @@ public final class Settings { "notifications_use_ring_volume"; /** + * Whether notifications should request audio focus. Could be disabled + * if a users favorite app behaves badly when audio focus is requested. + * Value is boolean. + * + * @hide + */ + public static final String NOTIFICATIONS_AUDIO_FOCUS = "notifications_audio_focus"; + + /** * Whether silent mode should allow vibration feedback. This is used * internally in AudioService and the Sound settings activity to * coordinate decoupling of vibrate and silent modes. This setting diff --git a/libs/audioflinger/AudioPolicyManagerBase.cpp b/libs/audioflinger/AudioPolicyManagerBase.cpp index c8b3f48..da62a8d 100644 --- a/libs/audioflinger/AudioPolicyManagerBase.cpp +++ b/libs/audioflinger/AudioPolicyManagerBase.cpp @@ -19,6 +19,8 @@ #include <utils/Log.h> #include <hardware_legacy/AudioPolicyManagerBase.h> #include <media/mediarecorder.h> +#include <cutils/properties.h> +#include <math.h> namespace android { @@ -1335,6 +1337,7 @@ void AudioPolicyManagerBase::checkOutputForAllStrategies(uint32_t &newDevice) // checkOutputForStrategy() checkOutputForStrategy(STRATEGY_PHONE, newDevice); checkOutputForStrategy(STRATEGY_SONIFICATION, newDevice); + checkOutputForStrategy(STRATEGY_MEDIA_SONIFICATION, newDevice); checkOutputForStrategy(STRATEGY_MEDIA, newDevice); checkOutputForStrategy(STRATEGY_DTMF, newDevice); } @@ -1351,15 +1354,19 @@ uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fro // use device for strategy phone // 2: the strategy sonification is active on the hardware output: // use device for strategy sonification - // 3: the strategy media is active on the hardware output: + // 3: the strategy media sonification is active on the hardware output: + // use device for strategy media sonification + // 4: the strategy media is active on the hardware output: // use device for strategy media - // 4: the strategy DTMF is active on the hardware output: + // 5: the strategy DTMF is active on the hardware output: // use device for strategy DTMF if (mPhoneState == AudioSystem::MODE_IN_CALL || outputDesc->isUsedByStrategy(STRATEGY_PHONE)) { device = getDeviceForStrategy(STRATEGY_PHONE, fromCache); } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) { device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache); + } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA_SONIFICATION)) { + device = getDeviceForStrategy(STRATEGY_MEDIA_SONIFICATION, fromCache); } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) { device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache); } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) { @@ -1372,14 +1379,36 @@ uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fro AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(AudioSystem::stream_type stream) { + // http://code.google.com/p/android/issues/detail?id=5012 + // http://code.google.com/p/cyanogenmod/issues/detail?id=1229 + char buf[PROPERTY_VALUE_MAX]; + // stream to strategy mapping switch (stream) { case AudioSystem::VOICE_CALL: case AudioSystem::BLUETOOTH_SCO: return STRATEGY_PHONE; case AudioSystem::RING: + property_get("persist.sys.ring-speaker", buf, "0"); + if (atoi(buf)) { + return STRATEGY_SONIFICATION; + } else { + return STRATEGY_MEDIA_SONIFICATION; + } case AudioSystem::NOTIFICATION: + property_get("persist.sys.notif-speaker", buf, "0"); + if (atoi(buf)) { + return STRATEGY_SONIFICATION; + } else { + return STRATEGY_MEDIA_SONIFICATION; + } case AudioSystem::ALARM: + property_get("persist.sys.alarm-speaker", buf, "0"); + if (atoi(buf)) { + return STRATEGY_SONIFICATION; + } else { + return STRATEGY_MEDIA_SONIFICATION; + } case AudioSystem::ENFORCED_AUDIBLE: return STRATEGY_SONIFICATION; case AudioSystem::DTMF: @@ -1472,6 +1501,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, break; case STRATEGY_SONIFICATION: + case STRATEGY_MEDIA_SONIFICATION: // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by // handleIncallSonification(). @@ -1479,9 +1509,11 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, device = getDeviceForStrategy(STRATEGY_PHONE, false); break; } - device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; - if (device == 0) { - LOGE("getDeviceForStrategy() speaker device not found"); + if (strategy == STRATEGY_SONIFICATION) { + device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER; + if (device == 0) { + LOGE("getDeviceForStrategy() speaker device not found"); + } } // The second device used for sonification is the same as the device used by media strategy // FALL THROUGH @@ -1675,20 +1707,67 @@ float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_hand AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | AudioSystem::DEVICE_OUT_WIRED_HEADSET | AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) && - (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) && + ((getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) || + (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_MEDIA_SONIFICATION)) && streamDesc.mCanBeMuted) { - volume *= SONIFICATION_HEADSET_VOLUME_FACTOR; + float origVol = volume; + char buf[PROPERTY_VALUE_MAX]; + float volumeFactor = SONIFICATION_HEADSET_VOLUME_FACTOR; + switch ((AudioSystem::stream_type)stream) { + case AudioSystem::RING: + LOGV("computeVolume RING"); + property_get("persist.sys.ring-attn", buf, "6"); + volumeFactor = pow(10.0, -atof(buf)/20.0); + break; + case AudioSystem::NOTIFICATION: + LOGV("computeVolume NOTIFICATION"); + property_get("persist.sys.notif-attn", buf, "6"); + volumeFactor = pow(10.0, -atof(buf)/20.0); + break; + case AudioSystem::ALARM: + LOGV("computeVolume ALARM"); + property_get("persist.sys.alarm-attn", buf, "6"); + volumeFactor = pow(10.0, -atof(buf)/20.0); + break; + default: + // Squash enumeration value not handled warnings + break; + } + LOGV("computeVolume attenuation factor %f ", volumeFactor); + volume *= volumeFactor; // when the phone is ringing we must consider that music could have been paused just before // by the music application and behave as if music was active if the last music track was // just stopped if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) { - float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device); - float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN; - if (volume > minVol) { - volume = minVol; - LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); + int limitVol = 1; + switch ((AudioSystem::stream_type)stream) { + case AudioSystem::RING: + property_get("persist.sys.ring-limitvol", buf, "1"); + limitVol = atoi(buf); + break; + case AudioSystem::NOTIFICATION: + property_get("persist.sys.notif-limitvol", buf, "1"); + limitVol = atoi(buf); + break; + case AudioSystem::ALARM: + property_get("persist.sys.alarm-limitvol", buf, "1"); + limitVol = atoi(buf); + break; + default: + // Squash enumeration value not handled warnings + break; + } + LOGV("computeVolume limitVol %i", limitVol); + if (limitVol) { + float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device); + float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN; + if (volume > minVol) { + volume = minVol; + LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); + } } } + LOGV("computeVolume %f --> %f", origVol, volume); } return volume; @@ -1792,7 +1871,8 @@ void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as // many times as there are active tracks on the output - if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) { + if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION || + getStrategy((AudioSystem::stream_type)stream) == STRATEGY_MEDIA_SONIFICATION) { AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput); LOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d", stream, starting, outputDesc->mDevice, stateChange); diff --git a/services/java/com/android/server/NotificationPlayer.java b/services/java/com/android/server/NotificationPlayer.java index 52d2381..e36fc6f 100644 --- a/services/java/com/android/server/NotificationPlayer.java +++ b/services/java/com/android/server/NotificationPlayer.java @@ -26,6 +26,7 @@ import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; +import android.provider.Settings; import android.util.Log; import java.io.IOException; @@ -88,7 +89,9 @@ public class NotificationPlayer implements OnCompletionListener { player.setDataSource(mCmd.context, mCmd.uri); player.setLooping(mCmd.looping); player.prepare(); - if ((mCmd.uri != null) && (mCmd.uri.getEncodedPath() != null) + boolean requestFocus = Settings.System.getInt(mCmd.context.getContentResolver(), + Settings.System.NOTIFICATIONS_AUDIO_FOCUS, 1) != 0; + if (requestFocus && (mCmd.uri != null) && (mCmd.uri.getEncodedPath() != null) && (mCmd.uri.getEncodedPath().length() > 0)) { if (mCmd.looping) { audioManager.requestAudioFocus(null, mCmd.stream, |