Add new audio mode for audio communications other than telelphony.

The audio mode MODE_IN_CALL signals the system the device a phone
 call is currently underway. There was no way for audio video
 chat or VoIP applications to signal a call is underway, but not
 using the telephony resources. This change introduces a new mode
 to address this. Changes in other parts of the system (java
 and native) are required to take this new mode into account.
The generic AudioPolicyManager is updated to not use its phone
 state variable directly, but to use two new convenience methods,
 isInCall() and isStateInCall(int) instead.

Change-Id: Id744cd26520ea1d1a4795eabe6a1f0c58789af76
This commit is contained in:
Jean-Michel Trivi
2010-11-15 12:11:32 -08:00
parent 75663ceec4
commit 8f677d66d9
7 changed files with 48 additions and 24 deletions

View File

@ -156,6 +156,7 @@ public:
MODE_NORMAL = 0,
MODE_RINGTONE,
MODE_IN_CALL,
MODE_IN_COMMUNICATION,
NUM_MODES // not a valid entry, denotes end-of-list
};

View File

@ -602,9 +602,9 @@ enum audio_device_e {
// Audio mode
enum audio_mode_e {
AUDIO_MODE_NORMAL, // phone idle
AUDIO_MODE_RINGTONE, // phone ringing
AUDIO_MODE_IN_CALL // phone call connected
AUDIO_MODE_NORMAL, // device idle
AUDIO_MODE_RINGTONE, // device ringing
AUDIO_MODE_IN_CALL // audio call connected (VoIP or telephony)
};
// Values for "accessMode" field of buffer_config_t:

View File

@ -984,7 +984,7 @@ public class AudioManager {
* application when it places a phone call, as it will cause signals from the radio layer
* to feed the platform mixer.
*
* @param mode the requested audio mode (NORMAL, RINGTONE, or IN_CALL).
* @param mode the requested audio mode (NORMAL, RINGTONE, IN_CALL or IN_COMMUNICATION).
* Informs the HAL about the current audio state so that
* it can route the audio appropriately.
*/
@ -1000,7 +1000,7 @@ public class AudioManager {
/**
* Returns the current audio mode.
*
* @return the current audio mode (NORMAL, RINGTONE, or IN_CALL).
* @return the current audio mode (NORMAL, RINGTONE, IN_CALL or IN_COMMUNICATION).
* Returns the current current audio state from the HAL.
*/
public int getMode() {
@ -1034,9 +1034,14 @@ public class AudioManager {
*/
public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE;
/**
* In call audio mode. A call is established.
* In call audio mode. A telephony call is established.
*/
public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL;
/**
* @hide
* In communication audio mode. An audio/video chat or VoIP call is established.
*/
public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION;
/* Routing bits for setRouting/getRouting API */
/**

View File

@ -718,7 +718,7 @@ public class AudioService extends IAudioService.Stub {
return;
}
if (mode < AudioSystem.MODE_CURRENT || mode > AudioSystem.MODE_IN_CALL) {
if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
return;
}
@ -2305,6 +2305,7 @@ public class AudioService extends IAudioService.Stub {
// add modify the phone app to take advantage of the new API
synchronized(mRingingLock) {
if (mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL) ||
(getMode() == AudioSystem.MODE_IN_COMMUNICATION) ||
(getMode() == AudioSystem.MODE_RINGTONE) ) {
return;
}

View File

@ -106,7 +106,8 @@ public class AudioSystem
public static final int MODE_NORMAL = 0;
public static final int MODE_RINGTONE = 1;
public static final int MODE_IN_CALL = 2;
public static final int NUM_MODES = 3;
public static final int MODE_IN_COMMUNICATION = 3;
public static final int NUM_MODES = 4;
/* Routing bits for setRouting/getRouting API */

View File

@ -5808,7 +5808,8 @@ uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t devic
const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = {
AUDIO_MODE_NORMAL, // AudioSystem::MODE_NORMAL
AUDIO_MODE_RINGTONE, // AudioSystem::MODE_RINGTONE
AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_CALL
AUDIO_MODE_IN_CALL, // AudioSystem::MODE_IN_CALL
AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_COMMUNICATION, same conversion as for MODE_IN_CALL
};
int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode)

View File

@ -246,7 +246,7 @@ void AudioPolicyManagerBase::setPhoneState(int state)
// if leaving call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
if (mPhoneState == AudioSystem::MODE_IN_CALL) {
if (isInCall()) {
LOGV("setPhoneState() in call state management: new state is %d", state);
for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
handleIncallSonification(stream, false, true);
@ -259,16 +259,21 @@ void AudioPolicyManagerBase::setPhoneState(int state)
bool force = false;
// are we entering or starting a call
if ((oldState != AudioSystem::MODE_IN_CALL) && (state == AudioSystem::MODE_IN_CALL)) {
if (!isStateInCall(oldState) && isStateInCall(state)) {
LOGV(" Entering call in setPhoneState()");
// force routing command to audio hardware when starting a call
// even if no device change is needed
force = true;
} else if ((oldState == AudioSystem::MODE_IN_CALL) && (state != AudioSystem::MODE_IN_CALL)) {
} else if (isStateInCall(oldState) && !isStateInCall(state)) {
LOGV(" Exiting call in setPhoneState()");
// force routing command to audio hardware when exiting a call
// even if no device change is needed
force = true;
} else if (isStateInCall(state) && (state != oldState)) {
LOGV(" Switching between telephony and VoIP in setPhoneState()");
// force routing command to audio hardware when switching between telephony and VoIP
// even if no device change is needed
force = true;
}
// check for device and output changes triggered by new phone state
@ -290,7 +295,7 @@ void AudioPolicyManagerBase::setPhoneState(int state)
// force routing command to audio hardware when ending call
// even if no device change is needed
if (oldState == AudioSystem::MODE_IN_CALL && newDevice == 0) {
if (isStateInCall(oldState) && newDevice == 0) {
newDevice = hwOutputDesc->device();
}
@ -298,7 +303,7 @@ void AudioPolicyManagerBase::setPhoneState(int state)
// immediately and delay the route change to avoid sending the ring tone
// tail into the earpiece or headset.
int delayMs = 0;
if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
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
@ -311,7 +316,7 @@ void AudioPolicyManagerBase::setPhoneState(int state)
// if entering in call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
if (state == AudioSystem::MODE_IN_CALL) {
if (isStateInCall(state)) {
LOGV("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
@ -586,7 +591,7 @@ status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output,
setOutputDevice(output, getNewDevice(output));
// handle special case for sonification while in call
if (mPhoneState == AudioSystem::MODE_IN_CALL) {
if (isInCall()) {
handleIncallSonification(stream, true, false);
}
@ -611,7 +616,7 @@ status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output,
routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
// handle special case for sonification while in call
if (mPhoneState == AudioSystem::MODE_IN_CALL) {
if (isInCall()) {
handleIncallSonification(stream, false, false);
}
@ -1478,7 +1483,7 @@ uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fro
// use device for strategy media
// 4: the strategy DTMF is active on the hardware output:
// use device for strategy DTMF
if (mPhoneState == AudioSystem::MODE_IN_CALL ||
if (isInCall() ||
outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
} else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
@ -1533,7 +1538,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy,
switch (strategy) {
case STRATEGY_DTMF:
if (mPhoneState != AudioSystem::MODE_IN_CALL) {
if (!isInCall()) {
// when off call, DTMF strategy follows the same rules as MEDIA strategy
device = getDeviceForStrategy(STRATEGY_MEDIA, false);
break;
@ -1546,7 +1551,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy,
// of priority
switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
case AudioSystem::FORCE_BT_SCO:
if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
if (!isInCall() || strategy != STRATEGY_DTMF) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
if (device) break;
}
@ -1566,7 +1571,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy,
if (device) break;
#ifdef WITH_A2DP
// when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
if (mPhoneState != AudioSystem::MODE_IN_CALL) {
if (!isInCall()) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
if (device) break;
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
@ -1580,14 +1585,14 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy,
break;
case AudioSystem::FORCE_SPEAKER:
if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
if (!isInCall() || strategy != STRATEGY_DTMF) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
if (device) break;
}
#ifdef WITH_A2DP
// when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
// A2DP speaker when forcing to speaker output
if (mPhoneState != AudioSystem::MODE_IN_CALL) {
if (!isInCall()) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
if (device) break;
}
@ -1604,7 +1609,7 @@ uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy,
// If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
// handleIncallSonification().
if (mPhoneState == AudioSystem::MODE_IN_CALL) {
if (isInCall()) {
device = getDeviceForStrategy(STRATEGY_PHONE, false);
break;
}
@ -1971,6 +1976,16 @@ void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting,
}
}
bool AudioPolicyManagerBase::isInCall()
{
return isStateInCall(mPhoneState);
}
bool AudioPolicyManagerBase::isStateInCall(int state) {
return ((state == AudioSystem::MODE_IN_CALL) ||
(state == AudioSystem::MODE_IN_COMMUNICATION));
}
bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
uint32_t samplingRate,
uint32_t format,