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,
|
static status_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
|
||||||
size_t* buffSize);
|
size_t* buffSize);
|
||||||
|
|
||||||
|
static status_t setVoiceVolume(float volume);
|
||||||
|
|
||||||
//
|
//
|
||||||
// AudioPolicyService interface
|
// AudioPolicyService interface
|
||||||
|
|||||||
@@ -102,10 +102,10 @@ public:
|
|||||||
|
|
||||||
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0;
|
virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0;
|
||||||
virtual String8 getParameters(int ioHandle, const String8& keys) = 0;
|
virtual String8 getParameters(int ioHandle, const String8& keys) = 0;
|
||||||
|
|
||||||
// register a current process for audio output change notifications
|
// register a current process for audio output change notifications
|
||||||
virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
|
virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
|
||||||
|
|
||||||
// retrieve the audio recording buffer size
|
// retrieve the audio recording buffer size
|
||||||
virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0;
|
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 closeInput(int input) = 0;
|
||||||
|
|
||||||
virtual status_t setStreamOutput(uint32_t stream, int output) = 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;
|
mStreamTypes[stream].volume = value;
|
||||||
|
|
||||||
if (thread == NULL) {
|
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);
|
mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
thread->setStreamVolume(stream, value);
|
thread->setStreamVolume(stream, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t AudioFlinger::setStreamMute(int stream, bool muted)
|
status_t AudioFlinger::setStreamMute(int stream, bool muted)
|
||||||
@@ -553,11 +532,6 @@ float AudioFlinger::streamVolume(int stream, int output) const
|
|||||||
volume = mStreamTypes[stream].volume;
|
volume = mStreamTypes[stream].volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove correction applied by setStreamVolume()
|
|
||||||
if (stream == AudioSystem::VOICE_CALL) {
|
|
||||||
volume = (volume - 0.01) / 0.99 ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,6 +618,21 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int cha
|
|||||||
return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
|
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)
|
void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ public:
|
|||||||
|
|
||||||
virtual status_t setStreamOutput(uint32_t stream, int output);
|
virtual status_t setStreamOutput(uint32_t stream, int output);
|
||||||
|
|
||||||
|
virtual status_t setVoiceVolume(float volume);
|
||||||
|
|
||||||
// IBinder::DeathRecipient
|
// IBinder::DeathRecipient
|
||||||
virtual void binderDied(const wp<IBinder>& who);
|
virtual void binderDied(const wp<IBinder>& who);
|
||||||
|
|
||||||
|
|||||||
@@ -495,6 +495,10 @@ status_t AudioPolicyService::stopTone()
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
|
||||||
|
{
|
||||||
|
return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------- AudioPolicyService::AudioCommandThread implementation ----------
|
// ----------- AudioPolicyService::AudioCommandThread implementation ----------
|
||||||
|
|
||||||
@@ -577,6 +581,16 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
|
|||||||
}
|
}
|
||||||
delete data;
|
delete data;
|
||||||
}break;
|
}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:
|
default:
|
||||||
LOGW("AudioCommandThread() unknown command %d", command->mCommand);
|
LOGW("AudioCommandThread() unknown command %d", command->mCommand);
|
||||||
}
|
}
|
||||||
@@ -597,7 +611,6 @@ bool AudioPolicyService::AudioCommandThread::threadLoop()
|
|||||||
|
|
||||||
void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
|
void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mLock);
|
|
||||||
AudioCommand *command = new AudioCommand();
|
AudioCommand *command = new AudioCommand();
|
||||||
command->mCommand = START_TONE;
|
command->mCommand = START_TONE;
|
||||||
ToneData *data = new ToneData();
|
ToneData *data = new ToneData();
|
||||||
@@ -605,6 +618,7 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre
|
|||||||
data->mStream = stream;
|
data->mStream = stream;
|
||||||
command->mParam = (void *)data;
|
command->mParam = (void *)data;
|
||||||
command->mWaitStatus = false;
|
command->mWaitStatus = false;
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
insertCommand_l(command);
|
insertCommand_l(command);
|
||||||
LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
|
LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
|
||||||
mWaitWorkCV.signal();
|
mWaitWorkCV.signal();
|
||||||
@@ -612,11 +626,11 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stre
|
|||||||
|
|
||||||
void AudioPolicyService::AudioCommandThread::stopToneCommand()
|
void AudioPolicyService::AudioCommandThread::stopToneCommand()
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mLock);
|
|
||||||
AudioCommand *command = new AudioCommand();
|
AudioCommand *command = new AudioCommand();
|
||||||
command->mCommand = STOP_TONE;
|
command->mCommand = STOP_TONE;
|
||||||
command->mParam = NULL;
|
command->mParam = NULL;
|
||||||
command->mWaitStatus = false;
|
command->mWaitStatus = false;
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
insertCommand_l(command);
|
insertCommand_l(command);
|
||||||
LOGV("AudioCommandThread() adding tone stop");
|
LOGV("AudioCommandThread() adding tone stop");
|
||||||
mWaitWorkCV.signal();
|
mWaitWorkCV.signal();
|
||||||
@@ -626,7 +640,6 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float
|
|||||||
{
|
{
|
||||||
status_t status = NO_ERROR;
|
status_t status = NO_ERROR;
|
||||||
|
|
||||||
Mutex::Autolock _l(mLock);
|
|
||||||
AudioCommand *command = new AudioCommand();
|
AudioCommand *command = new AudioCommand();
|
||||||
command->mCommand = SET_VOLUME;
|
command->mCommand = SET_VOLUME;
|
||||||
VolumeData *data = new VolumeData();
|
VolumeData *data = new VolumeData();
|
||||||
@@ -639,6 +652,7 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float
|
|||||||
} else {
|
} else {
|
||||||
command->mWaitStatus = false;
|
command->mWaitStatus = false;
|
||||||
}
|
}
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
insertCommand_l(command, delayMs);
|
insertCommand_l(command, delayMs);
|
||||||
LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
|
LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
|
||||||
mWaitWorkCV.signal();
|
mWaitWorkCV.signal();
|
||||||
@@ -654,7 +668,6 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
|
|||||||
{
|
{
|
||||||
status_t status = NO_ERROR;
|
status_t status = NO_ERROR;
|
||||||
|
|
||||||
Mutex::Autolock _l(mLock);
|
|
||||||
AudioCommand *command = new AudioCommand();
|
AudioCommand *command = new AudioCommand();
|
||||||
command->mCommand = SET_PARAMETERS;
|
command->mCommand = SET_PARAMETERS;
|
||||||
ParametersData *data = new ParametersData();
|
ParametersData *data = new ParametersData();
|
||||||
@@ -666,6 +679,7 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
|
|||||||
} else {
|
} else {
|
||||||
command->mWaitStatus = false;
|
command->mWaitStatus = false;
|
||||||
}
|
}
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
insertCommand_l(command, delayMs);
|
insertCommand_l(command, delayMs);
|
||||||
LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
|
LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
|
||||||
mWaitWorkCV.signal();
|
mWaitWorkCV.signal();
|
||||||
@@ -677,6 +691,32 @@ status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
|
|||||||
return status;
|
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
|
// insertCommand_l() must be called with mLock held
|
||||||
void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
|
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 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 startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream);
|
||||||
virtual status_t stopTone();
|
virtual status_t stopTone();
|
||||||
|
virtual status_t setVoiceVolume(float volume, int delayMs = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AudioPolicyService();
|
AudioPolicyService();
|
||||||
@@ -125,7 +126,8 @@ private:
|
|||||||
START_TONE,
|
START_TONE,
|
||||||
STOP_TONE,
|
STOP_TONE,
|
||||||
SET_VOLUME,
|
SET_VOLUME,
|
||||||
SET_PARAMETERS
|
SET_PARAMETERS,
|
||||||
|
SET_VOICE_VOLUME
|
||||||
};
|
};
|
||||||
|
|
||||||
AudioCommandThread ();
|
AudioCommandThread ();
|
||||||
@@ -140,6 +142,7 @@ private:
|
|||||||
void stopToneCommand();
|
void stopToneCommand();
|
||||||
status_t volumeCommand(int stream, float volume, int output, int delayMs = 0);
|
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 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);
|
void insertCommand_l(AudioCommand *command, int delayMs = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -166,12 +169,17 @@ private:
|
|||||||
float mVolume;
|
float mVolume;
|
||||||
int mIO;
|
int mIO;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ParametersData {
|
class ParametersData {
|
||||||
public:
|
public:
|
||||||
int mIO;
|
int mIO;
|
||||||
String8 mKeyValuePairs;
|
String8 mKeyValuePairs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VoiceVolumeData {
|
||||||
|
public:
|
||||||
|
float mVolume;
|
||||||
|
};
|
||||||
|
|
||||||
Mutex mLock;
|
Mutex mLock;
|
||||||
Condition mWaitWorkCV;
|
Condition mWaitWorkCV;
|
||||||
|
|||||||
@@ -335,6 +335,13 @@ status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int ch
|
|||||||
return NO_ERROR;
|
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) {
|
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ enum {
|
|||||||
RESTORE_OUTPUT,
|
RESTORE_OUTPUT,
|
||||||
OPEN_INPUT,
|
OPEN_INPUT,
|
||||||
CLOSE_INPUT,
|
CLOSE_INPUT,
|
||||||
SET_STREAM_OUTPUT
|
SET_STREAM_OUTPUT,
|
||||||
|
SET_VOICE_VOLUME
|
||||||
};
|
};
|
||||||
|
|
||||||
class BpAudioFlinger : public BpInterface<IAudioFlinger>
|
class BpAudioFlinger : public BpInterface<IAudioFlinger>
|
||||||
@@ -455,6 +456,15 @@ public:
|
|||||||
remote()->transact(SET_STREAM_OUTPUT, data, &reply);
|
remote()->transact(SET_STREAM_OUTPUT, data, &reply);
|
||||||
return reply.readInt32();
|
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");
|
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
|
||||||
@@ -700,6 +710,12 @@ status_t BnAudioFlinger::onTransact(
|
|||||||
reply->writeInt32(setStreamOutput(stream, output));
|
reply->writeInt32(setStreamOutput(stream, output));
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
} break;
|
} break;
|
||||||
|
case SET_VOICE_VOLUME: {
|
||||||
|
CHECK_INTERFACE(IAudioFlinger, data, reply);
|
||||||
|
float volume = data.readFloat();
|
||||||
|
reply->writeInt32( setVoiceVolume(volume) );
|
||||||
|
return NO_ERROR;
|
||||||
|
} break;
|
||||||
default:
|
default:
|
||||||
return BBinder::onTransact(code, data, reply, flags);
|
return BBinder::onTransact(code, data, reply, flags);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user