Merge change Icf10db28 into eclair
* changes: Fix issue 2192181: AudioFlinger must provide separated methods to set VOICE_CALL stream volume and down link audio volume.
This commit is contained in:
@@ -220,6 +220,7 @@ public:
|
||||
static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
|
||||
size_t* buffSize);
|
||||
|
||||
static status_t setVoiceVolume(float volume);
|
||||
|
||||
//
|
||||
// AudioPolicyService interface
|
||||
|
||||
@@ -102,10 +102,10 @@ public:
|
||||
|
||||
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0;
|
||||
virtual String8 getParameters(int ioHandle, const String8& keys) = 0;
|
||||
|
||||
|
||||
// register a current process for audio output change notifications
|
||||
virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
|
||||
|
||||
|
||||
// retrieve the audio recording buffer size
|
||||
virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0;
|
||||
|
||||
@@ -128,6 +128,8 @@ public:
|
||||
virtual status_t closeInput(int input) = 0;
|
||||
|
||||
virtual status_t setStreamOutput(uint32_t stream, int output) = 0;
|
||||
|
||||
virtual status_t setVoiceVolume(float volume) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -482,38 +482,17 @@ status_t AudioFlinger::setStreamVolume(int stream, float value, int output)
|
||||
}
|
||||
}
|
||||
|
||||
status_t ret = NO_ERROR;
|
||||
|
||||
if (stream == AudioSystem::VOICE_CALL ||
|
||||
stream == AudioSystem::BLUETOOTH_SCO) {
|
||||
float hwValue;
|
||||
if (stream == AudioSystem::VOICE_CALL) {
|
||||
hwValue = (float)AudioSystem::logToLinear(value)/100.0f;
|
||||
// offset value to reflect actual hardware volume that never reaches 0
|
||||
// 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
|
||||
value = 0.01 + 0.99 * value;
|
||||
} else { // (type == AudioSystem::BLUETOOTH_SCO)
|
||||
hwValue = 1.0f;
|
||||
}
|
||||
|
||||
AutoMutex lock(mHardwareLock);
|
||||
mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
|
||||
ret = mAudioHardware->setVoiceVolume(hwValue);
|
||||
mHardwareStatus = AUDIO_HW_IDLE;
|
||||
|
||||
}
|
||||
|
||||
mStreamTypes[stream].volume = value;
|
||||
|
||||
if (thread == NULL) {
|
||||
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
|
||||
for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
|
||||
mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
|
||||
|
||||
}
|
||||
} else {
|
||||
thread->setStreamVolume(stream, value);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t AudioFlinger::setStreamMute(int stream, bool muted)
|
||||
@@ -553,11 +532,6 @@ float AudioFlinger::streamVolume(int stream, int output) const
|
||||
volume = mStreamTypes[stream].volume;
|
||||
}
|
||||
|
||||
// remove correction applied by setStreamVolume()
|
||||
if (stream == AudioSystem::VOICE_CALL) {
|
||||
volume = (volume - 0.01) / 0.99 ;
|
||||
}
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
@@ -644,6 +618,21 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int cha
|
||||
return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
|
||||
}
|
||||
|
||||
status_t AudioFlinger::setVoiceVolume(float value)
|
||||
{
|
||||
// check calling permissions
|
||||
if (!settingsAllowed()) {
|
||||
return PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
AutoMutex lock(mHardwareLock);
|
||||
mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
|
||||
status_t ret = mAudioHardware->setVoiceVolume(value);
|
||||
mHardwareStatus = AUDIO_HW_IDLE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
|
||||
{
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@ public:
|
||||
|
||||
virtual status_t setStreamOutput(uint32_t stream, int output);
|
||||
|
||||
virtual status_t setVoiceVolume(float volume);
|
||||
|
||||
// IBinder::DeathRecipient
|
||||
virtual void binderDied(const wp<IBinder>& who);
|
||||
|
||||
|
||||
@@ -495,6 +495,10 @@ status_t AudioPolicyService::stopTone()
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
|
||||
{
|
||||
return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
|
||||
}
|
||||
|
||||
// ----------- AudioPolicyService::AudioCommandThread implementation ----------
|
||||
|
||||
@@ -577,6 +581,16 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
|
||||
}
|
||||
delete data;
|
||||
}break;
|
||||
case SET_VOICE_VOLUME: {
|
||||
VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
|
||||
LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume);
|
||||
command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
|
||||
if (command->mWaitStatus) {
|
||||
command->mCond.signal();
|
||||
mWaitWorkCV.wait(mLock);
|
||||
}
|
||||
delete data;
|
||||
}break;
|
||||
default:
|
||||
LOGW("AudioCommandThread() unknown command %d", command->mCommand);
|
||||
}
|
||||
@@ -597,7 +611,6 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
|
||||
|
||||
void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
|
||||
{
|
||||
Mutex::Autolock _l(mLock);
|
||||
AudioCommand *command = new AudioCommand();
|
||||
command->mCommand = START_TONE;
|
||||
ToneData *data = new ToneData();
|
||||
@@ -605,6 +618,7 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre
|
||||
data->mStream = stream;
|
||||
command->mParam = (void *)data;
|
||||
command->mWaitStatus = false;
|
||||
Mutex::Autolock _l(mLock);
|
||||
insertCommand_l(command);
|
||||
LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
|
||||
mWaitWorkCV.signal();
|
||||
@@ -612,11 +626,11 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre
|
||||
|
||||
void AudioPolicyService::AudioCommandThread::stopToneCommand()
|
||||
{
|
||||
Mutex::Autolock _l(mLock);
|
||||
AudioCommand *command = new AudioCommand();
|
||||
command->mCommand = STOP_TONE;
|
||||
command->mParam = NULL;
|
||||
command->mWaitStatus = false;
|
||||
Mutex::Autolock _l(mLock);
|
||||
insertCommand_l(command);
|
||||
LOGV("AudioCommandThread() adding tone stop");
|
||||
mWaitWorkCV.signal();
|
||||
@@ -626,7 +640,6 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float
|
||||
{
|
||||
status_t status = NO_ERROR;
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
AudioCommand *command = new AudioCommand();
|
||||
command->mCommand = SET_VOLUME;
|
||||
VolumeData *data = new VolumeData();
|
||||
@@ -639,6 +652,7 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float
|
||||
} else {
|
||||
command->mWaitStatus = false;
|
||||
}
|
||||
Mutex::Autolock _l(mLock);
|
||||
insertCommand_l(command, delayMs);
|
||||
LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
|
||||
mWaitWorkCV.signal();
|
||||
@@ -654,7 +668,6 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
|
||||
{
|
||||
status_t status = NO_ERROR;
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
AudioCommand *command = new AudioCommand();
|
||||
command->mCommand = SET_PARAMETERS;
|
||||
ParametersData *data = new ParametersData();
|
||||
@@ -666,6 +679,7 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
|
||||
} else {
|
||||
command->mWaitStatus = false;
|
||||
}
|
||||
Mutex::Autolock _l(mLock);
|
||||
insertCommand_l(command, delayMs);
|
||||
LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
|
||||
mWaitWorkCV.signal();
|
||||
@@ -677,6 +691,32 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
|
||||
{
|
||||
status_t status = NO_ERROR;
|
||||
|
||||
AudioCommand *command = new AudioCommand();
|
||||
command->mCommand = SET_VOICE_VOLUME;
|
||||
VoiceVolumeData *data = new VoiceVolumeData();
|
||||
data->mVolume = volume;
|
||||
command->mParam = data;
|
||||
if (delayMs == 0) {
|
||||
command->mWaitStatus = true;
|
||||
} else {
|
||||
command->mWaitStatus = false;
|
||||
}
|
||||
Mutex::Autolock _l(mLock);
|
||||
insertCommand_l(command, delayMs);
|
||||
LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
|
||||
mWaitWorkCV.signal();
|
||||
if (command->mWaitStatus) {
|
||||
command->mCond.wait(mLock);
|
||||
status = command->mStatus;
|
||||
mWaitWorkCV.signal();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// insertCommand_l() must be called with mLock held
|
||||
void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
|
||||
{
|
||||
|
||||
@@ -105,6 +105,7 @@ public:
|
||||
virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
|
||||
virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream);
|
||||
virtual status_t stopTone();
|
||||
virtual status_t setVoiceVolume(float volume, int delayMs = 0);
|
||||
|
||||
private:
|
||||
AudioPolicyService();
|
||||
@@ -125,7 +126,8 @@ private:
|
||||
START_TONE,
|
||||
STOP_TONE,
|
||||
SET_VOLUME,
|
||||
SET_PARAMETERS
|
||||
SET_PARAMETERS,
|
||||
SET_VOICE_VOLUME
|
||||
};
|
||||
|
||||
AudioCommandThread ();
|
||||
@@ -140,6 +142,7 @@ private:
|
||||
void stopToneCommand();
|
||||
status_t volumeCommand(int stream, float volume, int output, int delayMs = 0);
|
||||
status_t parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs = 0);
|
||||
status_t voiceVolumeCommand(float volume, int delayMs = 0);
|
||||
void insertCommand_l(AudioCommand *command, int delayMs = 0);
|
||||
|
||||
private:
|
||||
@@ -166,12 +169,17 @@ private:
|
||||
float mVolume;
|
||||
int mIO;
|
||||
};
|
||||
|
||||
class ParametersData {
|
||||
public:
|
||||
int mIO;
|
||||
String8 mKeyValuePairs;
|
||||
};
|
||||
|
||||
class VoiceVolumeData {
|
||||
public:
|
||||
float mVolume;
|
||||
};
|
||||
|
||||
Mutex mLock;
|
||||
Condition mWaitWorkCV;
|
||||
|
||||
@@ -335,6 +335,13 @@ status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int ch
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t AudioSystem::setVoiceVolume(float value)
|
||||
{
|
||||
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
|
||||
if (af == 0) return PERMISSION_DENIED;
|
||||
return af->setVoiceVolume(value);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
|
||||
|
||||
@@ -59,7 +59,8 @@ enum {
|
||||
RESTORE_OUTPUT,
|
||||
OPEN_INPUT,
|
||||
CLOSE_INPUT,
|
||||
SET_STREAM_OUTPUT
|
||||
SET_STREAM_OUTPUT,
|
||||
SET_VOICE_VOLUME
|
||||
};
|
||||
|
||||
class BpAudioFlinger : public BpInterface<IAudioFlinger>
|
||||
@@ -455,6 +456,15 @@ public:
|
||||
remote()->transact(SET_STREAM_OUTPUT, data, &reply);
|
||||
return reply.readInt32();
|
||||
}
|
||||
|
||||
virtual status_t setVoiceVolume(float volume)
|
||||
{
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
|
||||
data.writeFloat(volume);
|
||||
remote()->transact(SET_VOICE_VOLUME, data, &reply);
|
||||
return reply.readInt32();
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
|
||||
@@ -700,6 +710,12 @@ status_t BnAudioFlinger::onTransact(
|
||||
reply->writeInt32(setStreamOutput(stream, output));
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
case SET_VOICE_VOLUME: {
|
||||
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
||||
float volume = data.readFloat();
|
||||
reply->writeInt32( setVoiceVolume(volume) );
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
default:
|
||||
return BBinder::onTransact(code, data, reply, flags);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user