Merge "Audio: voice concurrency support for 8916"
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 4501239..03f6c41 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -595,7 +595,63 @@
return 0;
}
+#ifdef VOICE_CONCURRENCY
+ char propValue[PROPERTY_VALUE_MAX];
+ bool prop_rec_enabled=false, prop_voip_enabled = false;
+
+ if(property_get("voice.record.conc.disabled", propValue, NULL)) {
+ prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+ }
+
+ if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
+ prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+ }
+
+ if (prop_rec_enabled) {
+ //check if voice call is active / running in background
+ //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
+ //Need to block input request
+ if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+ ((AudioSystem::MODE_IN_CALL == mPrevPhoneState) &&
+ (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+ {
+ switch(inputSource) {
+ case AUDIO_SOURCE_VOICE_UPLINK:
+ case AUDIO_SOURCE_VOICE_DOWNLINK:
+ case AUDIO_SOURCE_VOICE_CALL:
+ ALOGD("Creating input during incall mode for inputSource: %d ",inputSource);
+ break;
+
+ case AUDIO_SOURCE_VOICE_COMMUNICATION:
+ if(prop_voip_enabled) {
+ ALOGD("BLOCKING VoIP request during incall mode for inputSource: %d ",inputSource);
+ return 0;
+ }
+ break;
+
+ default:
+ ALOGD("BLOCKING input during incall mode for inputSource: %d ",inputSource);
+ return 0;
+ }
+ }
+ }//check for VoIP flag
+ else if(prop_voip_enabled) {
+ //check if voice call is active / running in background
+ //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
+ //Need to block input request
+ if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+ ((AudioSystem::MODE_IN_CALL == mPrevPhoneState) &&
+ (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+ {
+ if(inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+ ALOGD("BLOCKING VoIP request during incall mode for inputSource: %d ",inputSource);
+ return 0;
+ }
+ }
+ }
+
+#endif
IOProfile *profile = getInputProfile(device,
samplingRate,
format,
@@ -1140,13 +1196,49 @@
IOProfile *profile = NULL;
#ifdef VOICE_CONCURRENCY
- if (isInCall()) {
- ALOGV(" IN call mode adding ULL flags .. flags: %x ", flags );
- //For voip paths
- if(flags & AudioSystem::OUTPUT_FLAG_DIRECT)
- flags = AudioSystem::OUTPUT_FLAG_DIRECT;
- else //route every thing else to ULL path
- flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+ char propValue[PROPERTY_VALUE_MAX];
+ bool prop_play_enabled=false, prop_voip_enabled = false;
+
+ if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
+ prop_play_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+ }
+
+ if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
+ prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+ }
+
+ if (prop_play_enabled) {
+ //check if voice call is active / running in background
+ if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+ ((AudioSystem::MODE_IN_CALL == mPrevPhoneState)
+ && (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+ {
+ if(AUDIO_OUTPUT_FLAG_VOIP_RX & flags) {
+ if(prop_voip_enabled) {
+ ALOGD(" IN call mode returing no output .. for VoIP usecase flags: %x ", flags );
+ // flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+ return 0;
+ }
+ }
+ else {
+ ALOGD(" IN call mode adding ULL flags .. flags: %x ", flags );
+ flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+ }
+ }
+ } else if (prop_voip_enabled) {
+ //check if voice call is active / running in background
+ //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
+ //return only ULL ouput
+ if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+ ((AudioSystem::MODE_IN_CALL == mPrevPhoneState)
+ && (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+ {
+ if(AUDIO_OUTPUT_FLAG_VOIP_RX & flags) {
+ ALOGD(" IN call mode returing no output .. for VoIP usecase flags: %x ", flags );
+ // flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+ return 0;
+ }
+ }
}
#endif
@@ -1329,11 +1421,18 @@
offloadInfo.has_video);
#ifdef VOICE_CONCURRENCY
- if(isInCall())
- {
- ALOGD("\n blocking compress offload on call mode\n");
- return false;
+ char concpropValue[PROPERTY_VALUE_MAX];
+ if(property_get("voice.playback.conc.disabled", concpropValue, NULL)) {
+ bool propenabled = atoi(concpropValue) || !strncmp("true", concpropValue, 4);
+ if (propenabled) {
+ if(isInCall())
+ {
+ ALOGD("\n blocking compress offload on call mode\n");
+ return false;
+ }
+ }
}
+
#endif
// Check if stream type is music, then only allow offload as of now.
if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
@@ -1441,7 +1540,7 @@
void AudioPolicyManager::setPhoneState(int state)
{
- ALOGV("setPhoneState() state %d", state);
+ ALOGD("setPhoneState() state %d", state);
audio_devices_t newDevice = AUDIO_DEVICE_NONE;
if (state < 0 || state >= AudioSystem::NUM_MODES) {
ALOGW("setPhoneState() invalid state %d", state);
@@ -1506,6 +1605,117 @@
if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
newDevice = hwOutputDesc->device();
}
+#ifdef VOICE_CONCURRENCY
+ char propValue[PROPERTY_VALUE_MAX];
+ bool prop_playback_enabled = false, prop_rec_enabled=false, prop_voip_enabled = false;
+
+ if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
+ prop_playback_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+ }
+
+ if(property_get("voice.record.conc.disabled", propValue, NULL)) {
+ prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+ }
+
+ if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
+ prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+ }
+
+ if((AudioSystem::MODE_IN_CALL != oldState) && (AudioSystem::MODE_IN_CALL == state)) {
+ ALOGD("Entering to call mode oldState :: %d state::%d ",oldState, state);
+
+ if(prop_playback_enabled) {
+ //Call invalidate to reset all opened non ULL audio tracks
+ // Move tracks associated to this strategy from previous output to new output
+ for (int i = AudioSystem::SYSTEM; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+ ALOGV(" Invalidate on call mode for stream :: %d ", i);
+ //FIXME see fixme on name change
+ mpClientInterface->setStreamOutput((AudioSystem::stream_type)i,
+ 0 /* ignored */);
+ }
+ }
+
+ if(prop_rec_enabled) {
+ //Close all active inputs
+ audio_io_handle_t activeInput = getActiveInput();
+ if (activeInput != 0) {
+ AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
+ switch(activeDesc->mInputSource) {
+ case AUDIO_SOURCE_VOICE_UPLINK:
+ case AUDIO_SOURCE_VOICE_DOWNLINK:
+ case AUDIO_SOURCE_VOICE_CALL:
+ ALOGD("FOUND active input during call active: %d",activeDesc->mInputSource);
+ break;
+
+ case AUDIO_SOURCE_VOICE_COMMUNICATION:
+ if(prop_voip_enabled) {
+ ALOGD("CLOSING VoIP input source on call setup :%d ",activeDesc->mInputSource);
+ stopInput(activeInput);
+ releaseInput(activeInput);
+ }
+ break;
+
+ default:
+ ALOGD("CLOSING input on call setup for inputSource: %d",activeDesc->mInputSource);
+ stopInput(activeInput);
+ releaseInput(activeInput);
+ break;
+ }
+ }
+ } else if(prop_voip_enabled) {
+ audio_io_handle_t activeInput = getActiveInput();
+ if (activeInput != 0) {
+ AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
+ if(AUDIO_SOURCE_VOICE_COMMUNICATION == activeDesc->mInputSource) {
+ ALOGD("CLOSING VoIP on call setup : %d",activeDesc->mInputSource);
+ stopInput(activeInput);
+ releaseInput(activeInput);
+ }
+ }
+ }
+
+ //suspend PCM (deep-buffer) output & close compress & direct tracks
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
+ if (((!outputDesc->isDuplicated() &&outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY))
+ && prop_playback_enabled) {
+ ALOGD(" calling suspendOutput on call mdoe for primary output");
+ mpClientInterface->suspendOutput(mOutputs.keyAt(i));
+ } //Close compress all sessions
+ else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
+ && prop_playback_enabled) {
+ ALOGD(" calling closeOutput on call mdoe for COMPRESS output");
+ closeOutput(mOutputs.keyAt(i));
+ }
+ else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)
+ && prop_voip_enabled) {
+ ALOGD(" calling closeOutput on call mdoe for DIRECT output");
+ closeOutput(mOutputs.keyAt(i));
+ }
+ }
+ }
+
+ if((AudioSystem::MODE_IN_CALL == oldState) && (AudioSystem::MODE_IN_CALL != state)
+ && prop_playback_enabled) {
+ ALOGD("EXITING from call mode oldState :: %d state::%d \n",oldState, state);
+ //restore PCM (deep-buffer) output after call termination
+ for (size_t i = 0; i < mOutputs.size(); i++) {
+ AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
+ if (!outputDesc->isDuplicated() &&outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
+ ALOGD("calling restoreOutput after call mode for primary output");
+ mpClientInterface->restoreOutput(mOutputs.keyAt(i));
+ }
+ }
+ //call invalidate tracks so that any open streams can fall back to deep buffer/compress path from ULL
+ for (int i = AudioSystem::SYSTEM; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+ ALOGD("Invalidate on call mode for stream :: %d ", i);
+ //FIXME see fixme on name change
+ mpClientInterface->setStreamOutput((AudioSystem::stream_type)i,
+ 0 /* ignored */);
+ }
+ }
+ mPrevPhoneState = oldState;
+#endif
int delayMs = 0;
if (isStateInCall(state)) {
@@ -1552,21 +1762,7 @@
} else {
mLimitRingtoneVolume = false;
}
-
-#ifdef VOICE_CONCURRENCY
- //Call invalidate to reset all opened non ULL audio tracks
- if(isInCall())
- {
- // Move tracks associated to this strategy from previous output to new output
- for (int i = AudioSystem::SYSTEM; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
- ALOGV("\n Invalidate on call mode for stream :: %d \n", i);
- //FIXME see fixme on name change
- mpClientInterface->setStreamOutput((AudioSystem::stream_type)i,
- 0 /* ignored */);
- }
- }
-#endif
-
+ ALOGD(" End of setPhoneState ... mPhoneState: %d ",mPhoneState);
}
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index ca7031d..f2488b2 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -106,8 +106,12 @@
//parameter indicates if HDMI plug in/out detected
bool mHdmiAudioEvent;
+
private:
void handleNotificationRoutingForStream(AudioSystem::stream_type stream);
+ // Used for voip + voice concurrency usecase
+ int mPrevPhoneState;
+
};
};