diff options
Diffstat (limited to 'audio')
| -rw-r--r-- | audio/AudioPolicyManagerBase.cpp | 174 | ||||
| -rw-r--r-- | audio/audio_hw_hal.cpp | 5 | ||||
| -rw-r--r-- | audio/audio_policy_hal.cpp | 42 |
3 files changed, 162 insertions, 59 deletions
diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index 45df7fe..3d198dc 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -319,13 +319,6 @@ void AudioPolicyManagerBase::setPhoneState(int state) } } -void AudioPolicyManagerBase::setRingerMode(uint32_t mode, uint32_t mask) -{ - ALOGV("setRingerMode() mode %x, mask %x", mode, mask); - - mRingerMode = mode; -} - void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) { ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState); @@ -573,8 +566,9 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, // necassary for a correct control of hardware output routing by startOutput() and stopOutput() outputDesc->changeRefCount(stream, 1); - uint32_t prevDevice = outputDesc->mDevice; + uint32_t prevDevice = outputDesc->device(); setOutputDevice(output, getNewDevice(output)); + uint32_t newDevice = outputDesc->device(); // handle special case for sonification while in call if (isInCall()) { @@ -582,12 +576,15 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, } // apply volume rules for current stream and device if necessary - checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device()); + checkAndSetVolume(stream, + mStreams[stream].getVolumeIndex((audio_devices_t)newDevice), + output, + newDevice); // FIXME: need a delay to make sure that audio path switches to speaker before sound // starts. Should be platform specific? if (stream == AudioSystem::ENFORCED_AUDIBLE && - prevDevice != outputDesc->mDevice) { + prevDevice != newDevice) { usleep(outputDesc->mLatency*4*1000); } @@ -814,18 +811,30 @@ void AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream, mStreams[stream].mIndexMax = indexMax; } -status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index) +status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, + int index, + audio_devices_t device) { if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { return BAD_VALUE; } + if (!audio_is_output_device(device)) { + return BAD_VALUE; + } // Force max volume if stream cannot be muted if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax; - ALOGV("setStreamVolumeIndex() stream %d, index %d", stream, index); - mStreams[stream].mIndexCur = index; + ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d", + stream, device, index); + + // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and + // clear all device specific values + if (device == AUDIO_DEVICE_OUT_DEFAULT) { + mStreams[stream].mIndexCur.clear(); + } + mStreams[stream].mIndexCur.add(device, index); // compute and apply stream volume on all outputs according to connected device status_t status = NO_ERROR; @@ -838,13 +847,25 @@ status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type s return status; } -status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) +status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, + int *index, + audio_devices_t device) { - if (index == 0) { + if (index == NULL) { + return BAD_VALUE; + } + if (!audio_is_output_device(device)) { return BAD_VALUE; } - ALOGV("getStreamVolumeIndex() stream %d", stream); - *index = mStreams[stream].mIndexCur; + // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to + // the strategy the stream belongs to. + if (device == AUDIO_DEVICE_OUT_DEFAULT) { + device = (audio_devices_t)getDeviceForStrategy(getStrategy(stream), true); + } + device = getDeviceForVolume(device); + + *index = mStreams[stream].getVolumeIndex(device); + ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index); return NO_ERROR; } @@ -998,9 +1019,6 @@ status_t AudioPolicyManagerBase::dump(int fd) result.append(buffer); snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState); result.append(buffer); -// disable ringer mode dump until it is actually passed by AudioService when needed. -// snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode); -// result.append(buffer); snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]); result.append(buffer); snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]); @@ -1029,12 +1047,13 @@ status_t AudioPolicyManagerBase::dump(int fd) snprintf(buffer, SIZE, "\nStreams dump:\n"); write(fd, buffer, strlen(buffer)); - snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Can be muted\n"); + snprintf(buffer, SIZE, + " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n"); write(fd, buffer, strlen(buffer)); for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) { - snprintf(buffer, SIZE, " %02d", i); - mStreams[i].dump(buffer + 3, SIZE); + snprintf(buffer, SIZE, " %02d ", i); write(fd, buffer, strlen(buffer)); + mStreams[i].dump(fd); } snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n", @@ -1062,7 +1081,7 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien #ifdef AUDIO_POLICY_TEST Thread(false), #endif //AUDIO_POLICY_TEST - mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), + mPhoneState(AudioSystem::MODE_NORMAL), mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f), mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0), mA2dpSuspended(false) @@ -1896,31 +1915,35 @@ audio_io_handle_t AudioPolicyManagerBase::getActiveInput() } -AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(uint32_t device) +audio_devices_t AudioPolicyManagerBase::getDeviceForVolume(audio_devices_t device) { if (device == 0) { // this happens when forcing a route update and no track is active on an output. // In this case the returned category is not important. - return DEVICE_CATEGORY_SPEAKER; - } - - if (AudioSystem::popCount(device) > 1) { + device = AUDIO_DEVICE_OUT_SPEAKER; + } else if (AudioSystem::popCount(device) > 1) { // Multiple device selection is either: // - speaker + one other device: give priority to speaker in this case. // - one A2DP device + another device: happens with duplicated output. In this case // retain the device on the A2DP output as the other must not correspond to an active // selection if not the speaker. - if (device & AUDIO_DEVICE_OUT_SPEAKER) - return DEVICE_CATEGORY_SPEAKER; - - device &= AUDIO_DEVICE_OUT_ALL_A2DP; + if (device & AUDIO_DEVICE_OUT_SPEAKER) { + device = AUDIO_DEVICE_OUT_SPEAKER; + } else { + device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP); + } } ALOGW_IF(AudioSystem::popCount(device) != 1, - "getDeviceCategory() invalid device combination: %08x", + "getDeviceForVolume() invalid device combination: %08x", device); - switch(device) { + return device; +} + +AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategory(uint32_t device) +{ + switch(getDeviceForVolume((audio_devices_t)device)) { case AUDIO_DEVICE_OUT_EARPIECE: return DEVICE_CATEGORY_EARPIECE; case AUDIO_DEVICE_OUT_WIRED_HEADSET: @@ -1933,6 +1956,7 @@ AudioPolicyManagerBase::device_category AudioPolicyManagerBase::getDeviceCategor case AUDIO_DEVICE_OUT_SPEAKER: case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT: case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER: + case AUDIO_DEVICE_OUT_AUX_DIGITAL: default: return DEVICE_CATEGORY_SPEAKER; } @@ -2046,7 +2070,10 @@ void AudioPolicyManagerBase::initializeVolumeCurves() } } -float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device) +float AudioPolicyManagerBase::computeVolume(int stream, + int index, + audio_io_handle_t output, + uint32_t device) { float volume = 1.0; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); @@ -2084,8 +2111,12 @@ float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_hand // 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; + float musicVol = computeVolume(AudioSystem::MUSIC, + mStreams[AudioSystem::MUSIC].getVolumeIndex((audio_devices_t)device), + output, + (uint32_t)device); + float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? + musicVol : SONIFICATION_HEADSET_VOLUME_MIN; if (volume > minVol) { volume = minVol; ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol); @@ -2096,7 +2127,12 @@ float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_hand return volume; } -status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force) +status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, + int index, + audio_io_handle_t output, + uint32_t device, + int delayMs, + bool force) { // do not change actual stream volume if the stream is muted @@ -2156,12 +2192,20 @@ status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_ return NO_ERROR; } -void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs, bool force) +void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, + uint32_t device, + int delayMs, + bool force) { ALOGV("applyStreamVolumes() for output %d and device %x", output, device); for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) { - checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs, force); + checkAndSetVolume(stream, + mStreams[stream].getVolumeIndex((audio_devices_t)device), + output, + device, + delayMs, + force); } } @@ -2179,13 +2223,14 @@ void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_ { StreamDescriptor &streamDesc = mStreams[stream]; AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output); + uint32_t device = outputDesc->device(); ALOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]); if (on) { if (outputDesc->mMuteCount[stream] == 0) { if (streamDesc.mCanBeMuted) { - checkAndSetVolume(stream, 0, output, outputDesc->device(), delayMs); + checkAndSetVolume(stream, 0, output, device, delayMs); } } // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored @@ -2196,7 +2241,11 @@ void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_ return; } if (--outputDesc->mMuteCount[stream] == 0) { - checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs); + checkAndSetVolume(stream, + streamDesc.getVolumeIndex((audio_devices_t)device), + output, + device, + delayMs); } } } @@ -2398,13 +2447,40 @@ status_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd) // --- StreamDescriptor class implementation -void AudioPolicyManagerBase::StreamDescriptor::dump(char* buffer, size_t size) +AudioPolicyManagerBase::StreamDescriptor::StreamDescriptor() + : mIndexMin(0), mIndexMax(1), mCanBeMuted(true) +{ + mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0); +} + +int AudioPolicyManagerBase::StreamDescriptor::getVolumeIndex(audio_devices_t device) +{ + device = AudioPolicyManagerBase::getDeviceForVolume(device); + // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT + if (mIndexCur.indexOfKey(device) < 0) { + device = AUDIO_DEVICE_OUT_DEFAULT; + } + return mIndexCur.valueFor(device); +} + +void AudioPolicyManagerBase::StreamDescriptor::dump(int fd) { - snprintf(buffer, size, " %02d %02d %02d %d\n", - mIndexMin, - mIndexMax, - mIndexCur, - mCanBeMuted); + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + + snprintf(buffer, SIZE, "%s %02d %02d ", + mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax); + result.append(buffer); + for (size_t i = 0; i < mIndexCur.size(); i++) { + snprintf(buffer, SIZE, "%04x : %02d, ", + mIndexCur.keyAt(i), + mIndexCur.valueAt(i)); + result.append(buffer); + } + result.append("\n"); + + write(fd, result.string(), result.size()); } // --- EffectDescriptor class implementation diff --git a/audio/audio_hw_hal.cpp b/audio/audio_hw_hal.cpp index 376bf25..a87db2f 100644 --- a/audio/audio_hw_hal.cpp +++ b/audio/audio_hw_hal.cpp @@ -348,10 +348,11 @@ static int adev_set_master_volume(struct audio_hw_device *dev, float volume) return ladev->hwif->setMasterVolume(volume); } -static int adev_set_mode(struct audio_hw_device *dev, int mode) +static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode) { struct legacy_audio_device *ladev = to_ladev(dev); - return ladev->hwif->setMode(mode); + // as this is the legacy API, don't change it to use audio_mode_t instead of int + return ladev->hwif->setMode((int) mode); } static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) diff --git a/audio/audio_policy_hal.cpp b/audio/audio_policy_hal.cpp index d19aed3..ae631f5 100644 --- a/audio/audio_policy_hal.cpp +++ b/audio/audio_policy_hal.cpp @@ -84,18 +84,18 @@ static audio_policy_dev_state_t ap_get_device_connection_state( device_address); } -static void ap_set_phone_state(struct audio_policy *pol, int state) +static void ap_set_phone_state(struct audio_policy *pol, audio_mode_t state) { struct legacy_audio_policy *lap = to_lap(pol); - lap->apm->setPhoneState(state); + // as this is the legacy API, don't change it to use audio_mode_t instead of int + lap->apm->setPhoneState((int) state); } /* indicate a change in ringer mode */ static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode, uint32_t mask) { - struct legacy_audio_policy *lap = to_lap(pol); - lap->apm->setRingerMode(mode, mask); + // deprecated, never called } /* force using a specific device category for the specified usage */ @@ -215,7 +215,8 @@ static int ap_set_stream_volume_index(struct audio_policy *pol, { struct legacy_audio_policy *lap = to_lap(pol); return lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream, - index); + index, + AUDIO_DEVICE_OUT_DEFAULT); } static int ap_get_stream_volume_index(const struct audio_policy *pol, @@ -224,7 +225,30 @@ static int ap_get_stream_volume_index(const struct audio_policy *pol, { const struct legacy_audio_policy *lap = to_clap(pol); return lap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream, - index); + index, + AUDIO_DEVICE_OUT_DEFAULT); +} + +static int ap_set_stream_volume_index_for_device(struct audio_policy *pol, + audio_stream_type_t stream, + int index, + audio_devices_t device) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream, + index, + device); +} + +static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index, + audio_devices_t device) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream, + index, + device); } static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol, @@ -271,11 +295,11 @@ static int ap_set_effect_enabled(struct audio_policy *pol, int id, bool enabled) return lap->apm->setEffectEnabled(id, enabled); } -static bool ap_is_stream_active(const struct audio_policy *pol, int stream, +static bool ap_is_stream_active(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->isStreamActive(stream, in_past_ms); + return lap->apm->isStreamActive((int) stream, in_past_ms); } static int ap_dump(const struct audio_policy *pol, int fd) @@ -319,6 +343,8 @@ static int create_legacy_ap(const struct audio_policy_device *device, lap->policy.init_stream_volume = ap_init_stream_volume; lap->policy.set_stream_volume_index = ap_set_stream_volume_index; lap->policy.get_stream_volume_index = ap_get_stream_volume_index; + lap->policy.set_stream_volume_index_for_device = ap_set_stream_volume_index_for_device; + lap->policy.get_stream_volume_index_for_device = ap_get_stream_volume_index_for_device; lap->policy.get_strategy_for_stream = ap_get_strategy_for_stream; lap->policy.get_devices_for_stream = ap_get_devices_for_stream; lap->policy.get_output_for_effect = ap_get_output_for_effect; |
