Merge "hal: end all calls when setmode(AUDIO_MODE_NORMAL) is called"
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index b661dd1..9ce8e19 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -98,7 +98,7 @@
.format = PCM_FORMAT_S16_LE,
};
-static const char * const use_case_table[AUDIO_USECASE_MAX] = {
+const char * const use_case_table[AUDIO_USECASE_MAX] = {
[USECASE_AUDIO_PLAYBACK_DEEP_BUFFER] = "deep-buffer-playback",
[USECASE_AUDIO_PLAYBACK_LOW_LATENCY] = "low-latency-playback",
[USECASE_AUDIO_PLAYBACK_MULTI_CH] = "multi-channel-playback",
@@ -2089,7 +2089,9 @@
int val;
int ret;
- ALOGV("%s: enter: %s", __func__, kvpairs);
+ ALOGD("%s: enter: %s", __func__, kvpairs);
+
+ pthread_mutex_lock(&adev->lock);
parms = str_parms_create_str(kvpairs);
voice_set_parameters(adev, parms);
@@ -2131,7 +2133,6 @@
default:
ALOGE("%s: unexpected rotation of %d", __func__, val);
}
- pthread_mutex_lock(&adev->lock);
if (adev->speaker_lr_swap != reverse_speakers) {
adev->speaker_lr_swap = reverse_speakers;
// only update the selected device if there is active pcm playback
@@ -2145,11 +2146,12 @@
}
}
}
- pthread_mutex_unlock(&adev->lock);
}
audio_extn_set_parameters(adev, parms);
str_parms_destroy(parms);
+
+ pthread_mutex_unlock(&adev->lock);
ALOGV("%s: exit with code(%d)", __func__, ret);
return ret;
}
@@ -2162,12 +2164,15 @@
struct str_parms *query = str_parms_create_str(keys);
char *str;
+ pthread_mutex_lock(&adev->lock);
+
audio_extn_get_parameters(adev, query, reply);
platform_get_parameters(adev->platform, query, reply);
str = str_parms_to_str(reply);
str_parms_destroy(query);
str_parms_destroy(reply);
+ pthread_mutex_unlock(&adev->lock);
ALOGV("%s: exit: returns - %s", __func__, str);
return str;
}
@@ -2223,7 +2228,13 @@
static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
{
- return voice_set_mic_mute((struct audio_device *)dev, state);
+ int ret;
+
+ pthread_mutex_lock(&adev->lock);
+ ret = voice_set_mic_mute((struct audio_device *)dev, state);
+ pthread_mutex_unlock(&adev->lock);
+
+ return ret;
}
static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e9cb493..2aaaf4a 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1092,19 +1092,15 @@
ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_BTSCO, &val);
if (ret >= 0) {
str_parms_del(parms, AUDIO_PARAMETER_KEY_BTSCO);
- pthread_mutex_lock(&my_data->adev->lock);
my_data->btsco_sample_rate = val;
- pthread_mutex_unlock(&my_data->adev->lock);
}
ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_SLOWTALK, &val);
if (ret >= 0) {
str_parms_del(parms, AUDIO_PARAMETER_KEY_SLOWTALK);
- pthread_mutex_lock(&my_data->adev->lock);
ret = platform_set_slowtalk(my_data, val);
if (ret)
ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
- pthread_mutex_unlock(&my_data->adev->lock);
}
ALOGV("%s: exit with code(%d)", __func__, ret);
@@ -1154,7 +1150,6 @@
ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_FLUENCE_TYPE,
value, sizeof(value));
if (ret >= 0) {
- pthread_mutex_lock(&my_data->adev->lock);
if (my_data->fluence_type & FLUENCE_QUAD_MIC) {
strlcpy(value, "fluencepro", sizeof(value));
} else if (my_data->fluence_type & FLUENCE_DUAL_MIC) {
@@ -1162,7 +1157,6 @@
} else {
strlcpy(value, "none", sizeof(value));
}
- pthread_mutex_unlock(&my_data->adev->lock);
str_parms_add_str(reply, AUDIO_PARAMETER_KEY_FLUENCE_TYPE, value);
}
diff --git a/hal/voice.c b/hal/voice.c
index 907ebc9..c85fcd4 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -41,20 +41,7 @@
.format = PCM_FORMAT_S16_LE,
};
-extern struct audio_usecase *get_usecase_from_list(struct audio_device *adev,
- audio_usecase_t uc_id);
-extern int disable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer);
-extern int disable_audio_route(struct audio_device *adev,
- struct audio_usecase *usecase,
- bool update_mixer);
-
-extern int disable_snd_device(struct audio_device *adev,
- snd_device_t snd_device,
- bool update_mixer);
-extern int select_devices(struct audio_device *adev,
- audio_usecase_t uc_id);
+extern const char * const use_case_table[AUDIO_USECASE_MAX];
static struct voice_session *voice_get_session_from_use_case(struct audio_device *adev,
audio_usecase_t usecase_id)
@@ -76,7 +63,7 @@
struct audio_usecase *uc_info;
struct voice_session *session = NULL;
- ALOGD("%s: enter", __func__);
+ ALOGD("%s: enter usecase:%s", __func__, use_case_table[usecase_id]);
session = (struct voice_session *)voice_get_session_from_use_case(adev, usecase_id);
session->state.current = CALL_INACTIVE;
@@ -124,10 +111,10 @@
int pcm_dev_rx_id, pcm_dev_tx_id;
struct voice_session *session = NULL;
struct pcm_config voice_config = pcm_config_voice_call;
- ALOGD("%s: enter", __func__);
+
+ ALOGD("%s: enter usecase:%s", __func__, use_case_table[usecase_id]);
session = (struct voice_session *)voice_get_session_from_use_case(adev, usecase_id);
-
uc_info = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
uc_info->id = usecase_id;
uc_info->type = VOICE_CALL;
@@ -274,14 +261,11 @@
{
int err = 0;
- pthread_mutex_lock(&adev->lock);
-
err = platform_set_mic_mute(adev->platform, state);
if (!err) {
adev->voice.mic_mute = state;
}
- pthread_mutex_unlock(&adev->lock);
return err;
}
@@ -319,7 +303,7 @@
{
int ret = 0;
- ret = voice_extn_update_calls(adev);
+ ret = voice_extn_start_call(adev);
if (ret == -ENOSYS) {
ret = start_call(adev, USECASE_VOICE_CALL);
}
@@ -331,7 +315,7 @@
{
int ret = 0;
- ret = voice_extn_update_calls(adev);
+ ret = voice_extn_stop_call(adev);
if (ret == -ENOSYS) {
ret = stop_call(adev, USECASE_VOICE_CALL);
}
@@ -367,7 +351,6 @@
goto done;
}
- pthread_mutex_lock(&adev->lock);
if (tty_mode != adev->voice.tty_mode) {
adev->voice.tty_mode = tty_mode;
adev->acdb_settings = (adev->acdb_settings & TTY_MODE_CLEAR) | tty_mode;
@@ -375,7 +358,6 @@
//todo: what about voice2, volte and qchat usecases?
select_devices(adev, USECASE_VOICE_CALL);
}
- pthread_mutex_unlock(&adev->lock);
}
done:
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 903d2aa..87a97e2 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -63,7 +63,7 @@
extern int start_call(struct audio_device *adev, audio_usecase_t usecase_id);
extern int stop_call(struct audio_device *adev, audio_usecase_t usecase_id);
-int voice_extn_update_calls(struct audio_device *adev);
+int voice_extn_is_in_call(struct audio_device *adev, bool *in_call);
static bool is_valid_call_state(int call_state)
{
@@ -130,104 +130,7 @@
return session_id;
}
-int voice_extn_get_active_session_id(struct audio_device *adev,
- uint32_t *session_id)
-{
- *session_id = get_session_id_with_state(adev, CALL_ACTIVE);
- return 0;
-}
-
-int voice_extn_is_in_call(struct audio_device *adev, bool *in_call)
-{
- struct voice_session *session = NULL;
- int i = 0;
- *in_call = false;
-
- for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
- session = &adev->voice.session[i];
- if(session->state.current != CALL_INACTIVE){
- *in_call = true;
- break;
- }
- }
-
- return 0;
-}
-
-static int voice_extn_update_call_states(struct audio_device *adev,
- const uint32_t vsid, const int call_state)
-{
- struct voice_session *session = NULL;
- int i = 0;
- bool is_in_call;
-
- for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
- if (vsid == adev->voice.session[i].vsid) {
- session = &adev->voice.session[i];
- break;
- }
- }
-
- if (session) {
- session->state.new = call_state;
- voice_extn_is_in_call(adev, &is_in_call);
- ALOGD("%s is_in_call:%d mode:%d\n", __func__, is_in_call, adev->mode);
- if (is_in_call || adev->mode == AUDIO_MODE_IN_CALL) {
- /* Device routing is not triggered for voice calls on the subsequent
- * subs, Hence update the call states if voice call is already
- * active on other sub.
- */
- voice_extn_update_calls(adev);
- }
- } else {
- return -EINVAL;
- }
-
- return 0;
-
-}
-
-void voice_extn_init(struct audio_device *adev)
-{
- adev->voice.session[VOICE_SESS_IDX].vsid = VOICE_VSID;
- adev->voice.session[VOICE2_SESS_IDX].vsid = VOICE2_VSID;
- adev->voice.session[VOLTE_SESS_IDX].vsid = VOLTE_VSID;
- adev->voice.session[QCHAT_SESS_IDX].vsid = QCHAT_VSID;
-}
-
-int voice_extn_get_session_from_use_case(struct audio_device *adev,
- const audio_usecase_t usecase_id,
- struct voice_session **session)
-{
-
- switch(usecase_id)
- {
- case USECASE_VOICE_CALL:
- *session = &adev->voice.session[VOICE_SESS_IDX];
- break;
-
- case USECASE_VOICE2_CALL:
- *session = &adev->voice.session[VOICE2_SESS_IDX];
- break;
-
- case USECASE_VOLTE_CALL:
- *session = &adev->voice.session[VOLTE_SESS_IDX];
- break;
-
- case USECASE_QCHAT_CALL:
- *session = &adev->voice.session[QCHAT_SESS_IDX];
- break;
-
- default:
- ALOGE("%s: Invalid usecase_id:%d\n", __func__, usecase_id);
- *session = NULL;
- return -EINVAL;
- }
-
- return 0;
-}
-
-int voice_extn_update_calls(struct audio_device *adev)
+static int update_calls(struct audio_device *adev)
{
int i = 0;
audio_usecase_t usecase_id = 0;
@@ -255,8 +158,9 @@
if(ret < 0) {
ALOGE("%s: voice_start_call() failed for usecase: %d\n",
__func__, usecase_id);
+ } else {
+ session->state.current = session->state.new;
}
- session->state.current = session->state.new;
break;
case CALL_HOLD:
@@ -292,8 +196,9 @@
if(ret < 0) {
ALOGE("%s: voice_end_call() failed for usecase: %d\n",
__func__, usecase_id);
+ } else {
+ session->state.current = session->state.new;
}
- session->state.current = session->state.new;
break;
default:
@@ -358,6 +263,136 @@
return ret;
}
+static int update_call_states(struct audio_device *adev,
+ const uint32_t vsid, const int call_state)
+{
+ struct voice_session *session = NULL;
+ int i = 0;
+ bool is_in_call;
+
+ for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
+ if (vsid == adev->voice.session[i].vsid) {
+ session = &adev->voice.session[i];
+ break;
+ }
+ }
+
+ if (session) {
+ session->state.new = call_state;
+ voice_extn_is_in_call(adev, &is_in_call);
+ ALOGD("%s is_in_call:%d mode:%d\n", __func__, is_in_call, adev->mode);
+ if (is_in_call || adev->mode == AUDIO_MODE_IN_CALL) {
+ /* Device routing is not triggered for voice calls on the subsequent
+ * subs, Hence update the call states if voice call is already
+ * active on other sub.
+ */
+ update_calls(adev);
+ }
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+
+}
+
+int voice_extn_get_active_session_id(struct audio_device *adev,
+ uint32_t *session_id)
+{
+ *session_id = get_session_id_with_state(adev, CALL_ACTIVE);
+ return 0;
+}
+
+int voice_extn_is_in_call(struct audio_device *adev, bool *in_call)
+{
+ struct voice_session *session = NULL;
+ int i = 0;
+ *in_call = false;
+
+ for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
+ session = &adev->voice.session[i];
+ if(session->state.current != CALL_INACTIVE){
+ *in_call = true;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+void voice_extn_init(struct audio_device *adev)
+{
+ adev->voice.session[VOICE_SESS_IDX].vsid = VOICE_VSID;
+ adev->voice.session[VOICE2_SESS_IDX].vsid = VOICE2_VSID;
+ adev->voice.session[VOLTE_SESS_IDX].vsid = VOLTE_VSID;
+ adev->voice.session[QCHAT_SESS_IDX].vsid = QCHAT_VSID;
+}
+
+int voice_extn_get_session_from_use_case(struct audio_device *adev,
+ const audio_usecase_t usecase_id,
+ struct voice_session **session)
+{
+
+ switch(usecase_id)
+ {
+ case USECASE_VOICE_CALL:
+ *session = &adev->voice.session[VOICE_SESS_IDX];
+ break;
+
+ case USECASE_VOICE2_CALL:
+ *session = &adev->voice.session[VOICE2_SESS_IDX];
+ break;
+
+ case USECASE_VOLTE_CALL:
+ *session = &adev->voice.session[VOLTE_SESS_IDX];
+ break;
+
+ case USECASE_QCHAT_CALL:
+ *session = &adev->voice.session[QCHAT_SESS_IDX];
+ break;
+
+ default:
+ ALOGE("%s: Invalid usecase_id:%d\n", __func__, usecase_id);
+ *session = NULL;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int voice_extn_start_call(struct audio_device *adev)
+{
+ /* Start voice calls on sessions whose call state has been
+ * udpated.
+ */
+ ALOGV("%s: enter:", __func__);
+ return update_calls(adev);
+}
+
+int voice_extn_stop_call(struct audio_device *adev)
+{
+ int i;
+ int ret = 0;
+
+ ALOGV("%s: enter:", __func__);
+
+ /* If BT device is enabled and voice calls are ended, telephony will call
+ * set_mode(AUDIO_MODE_NORMAL) which will trigger audio policy manager to
+ * set routing with device BT A2DP profile. Hence end all voice calls when
+ * set_mode(AUDIO_MODE_NORMAL) before BT A2DP profile is selected.
+ */
+ if (adev->mode == AUDIO_MODE_NORMAL) {
+ ALOGD("%s: end all calls", __func__);
+ for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
+ adev->voice.session[i].state.new = CALL_INACTIVE;
+ }
+
+ ret = update_calls(adev);
+ }
+
+ return ret;
+}
+
int voice_extn_set_parameters(struct audio_device *adev,
struct str_parms *parms)
{
@@ -375,7 +410,6 @@
ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_CALL_STATE, &value);
if (ret >= 0) {
call_state = value;
- //validate callstate
} else {
ALOGE("%s: call_state key not found", __func__);
ret = -EINVAL;
@@ -383,11 +417,10 @@
}
if (is_valid_vsid(vsid) && is_valid_call_state(call_state)) {
- pthread_mutex_lock(&adev->lock);
- voice_extn_update_call_states(adev, vsid, call_state);
- pthread_mutex_unlock(&adev->lock);
+ ret = update_call_states(adev, vsid, call_state);
} else {
- ALOGE("%s: invalid vsid or call_state", __func__);
+ ALOGE("%s: invalid vsid:%x or call_state:%d",
+ __func__, vsid, call_state);
ret = -EINVAL;
goto done;
}
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index dd2dfd8..c4e2131 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -21,18 +21,24 @@
#define VOICE_EXTN_H
#ifdef MULTI_VOICE_SESSION_ENABLED
-int voice_extn_update_calls(struct audio_device *adev);
+int voice_extn_start_call(struct audio_device *adev);
+int voice_extn_stop_call(struct audio_device *adev);
int voice_extn_get_session_from_use_case(struct audio_device *adev,
const audio_usecase_t usecase_id,
struct voice_session **session);
-int voice_extn_init(struct audio_device *adev);
+void voice_extn_init(struct audio_device *adev);
int voice_extn_set_parameters(struct audio_device *adev,
struct str_parms *parms);
int voice_extn_is_in_call(struct audio_device *adev, bool *in_call);
int voice_extn_get_active_session_id(struct audio_device *adev,
uint32_t *session_id);
#else
-static int voice_extn_update_calls(struct audio_device *adev)
+static int voice_extn_start_call(struct audio_device *adev)
+{
+ return -ENOSYS;
+}
+
+static int voice_extn_stop_call(struct audio_device *adev)
{
return -ENOSYS;
}
@@ -44,9 +50,8 @@
return -ENOSYS;
}
-static int voice_extn_init(struct audio_device *adev)
+static void voice_extn_init(struct audio_device *adev)
{
- return -ENOSYS;
}
static int voice_extn_set_parameters(struct audio_device *adev,