Merge "hal_mpq: Fix the underrun issue in the offload playback"
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index e17aa6b..72f8642 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -165,4 +165,10 @@
int audio_extn_dolby_set_DMID(struct audio_device *adev);
#endif
+#ifndef HFP_ENABLED
+#define audio_extn_hfp_is_active(adev) (0)
+#else
+bool audio_extn_hfp_is_active(struct audio_device *adev);
+#endif
+
#endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/hfp.c b/hal/audio_extn/hfp.c
index 4eb9d37..2d6e1e0 100644
--- a/hal/audio_extn/hfp.c
+++ b/hal/audio_extn/hfp.c
@@ -217,10 +217,22 @@
return ret;
}
+bool audio_extn_hfp_is_active(struct audio_device *adev)
+{
+ struct audio_usecase *hfp_usecase = NULL;
+ hfp_usecase = get_usecase_from_list(adev, USECASE_AUDIO_HFP_SCO);
+
+ if (hfp_usecase != NULL)
+ return true;
+ else
+ return false;
+}
+
void audio_extn_hfp_set_parameters(struct audio_device *adev, struct str_parms *parms)
{
int ret;
int rate;
+ int val;
char value[32]={0};
ret = str_parms_get_str(parms, AUDIO_PARAMETER_HFP_ENABLE, value,
@@ -247,5 +259,16 @@
else
ALOGE("Unsupported rate..");
}
+
+ if(hfpmod.is_hfp_running) {
+ memset(value, 0, sizeof(value));
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
+ value, sizeof(value));
+ if (ret >= 0) {
+ val = atoi(value);
+ if(val > 0)
+ select_devices(adev, hfpmod.ucid);
+ }
+ }
}
#endif /*HFP_ENABLED*/
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index ee68a8f..61e291d 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -153,6 +153,7 @@
static int set_voice_volume_l(struct audio_device *adev, float volume);
static uint32_t get_offload_buffer_size();
+static int set_gapless_mode(struct audio_device *adev);
static bool is_supported_format(audio_format_t format)
{
@@ -369,7 +370,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK &&
+ if (usecase->type != PCM_CAPTURE &&
usecase != uc_info &&
usecase->out_snd_device != snd_device &&
usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
@@ -413,8 +414,6 @@
enable_audio_route(adev, usecase, false);
}
}
-
- audio_route_update_mixer(adev->audio_route);
}
}
@@ -442,7 +441,7 @@
list_for_each(node, &adev->usecase_list) {
usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_CAPTURE &&
+ if (usecase->type != PCM_PLAYBACK &&
usecase != uc_info &&
usecase->in_snd_device != snd_device) {
ALOGV("%s: Usecase (%s) is active on (%s) - disabling ..",
@@ -462,6 +461,12 @@
usecase = node_to_item(node, struct audio_usecase, list);
if (switch_device[usecase->id]) {
disable_snd_device(adev, usecase->in_snd_device, false);
+ }
+ }
+
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (switch_device[usecase->id]) {
enable_snd_device(adev, snd_device, false);
}
}
@@ -479,57 +484,9 @@
enable_audio_route(adev, usecase, false);
}
}
-
- audio_route_update_mixer(adev->audio_route);
}
}
-static int disable_all_usecases_of_type(struct audio_device *adev,
- usecase_type_t usecase_type,
- bool update_mixer)
-{
- struct audio_usecase *usecase;
- struct listnode *node;
- int ret = 0;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == usecase_type) {
- ALOGV("%s: usecase id %d", __func__, usecase->id);
- ret = disable_audio_route(adev, usecase, update_mixer);
- if (ret) {
- ALOGE("%s: Failed to disable usecase id %d",
- __func__, usecase->id);
- }
- }
- }
-
- return ret;
-}
-
-static int enable_all_usecases_of_type(struct audio_device *adev,
- usecase_type_t usecase_type,
- bool update_mixer)
-{
- struct audio_usecase *usecase;
- struct listnode *node;
- int ret = 0;
-
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == usecase_type) {
- ALOGV("%s: usecase id %d", __func__, usecase->id);
- ret = enable_audio_route(adev, usecase, update_mixer);
- if (ret) {
- ALOGE("%s: Failed to enable usecase id %d",
- __func__, usecase->id);
- }
- }
- }
-
- return ret;
-}
-
/* must be called with hw device mutex locked */
static int read_hdmi_channel_masks(struct stream_out *out)
{
@@ -558,6 +515,21 @@
return ret;
}
+static void update_devices_for_all_voice_usecases(struct audio_device *adev)
+{
+ struct listnode *node;
+ struct audio_usecase *usecase;
+
+ list_for_each(node, &adev->usecase_list) {
+ usecase = node_to_item(node, struct audio_usecase, list);
+ if (usecase->type == VOICE_CALL) {
+ ALOGV("%s: updating device for usecase:%s", __func__,
+ use_case_table[usecase->id]);
+ select_devices(adev, usecase->id);
+ }
+ }
+}
+
static audio_usecase_t get_voice_usecase_id_from_list(struct audio_device *adev)
{
struct audio_usecase *usecase;
@@ -594,6 +566,7 @@
struct audio_usecase *usecase = NULL;
struct audio_usecase *vc_usecase = NULL;
struct audio_usecase *voip_usecase = NULL;
+ struct audio_usecase *hfp_usecase = NULL;
struct listnode *node;
int status = 0;
@@ -632,6 +605,12 @@
in_snd_device = voip_usecase->in_snd_device;
out_snd_device = voip_usecase->out_snd_device;
}
+ } else if (audio_extn_hfp_is_active(adev)) {
+ hfp_usecase = get_usecase_from_list(adev, USECASE_AUDIO_HFP_SCO);
+ if (hfp_usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) {
+ in_snd_device = hfp_usecase->in_snd_device;
+ out_snd_device = hfp_usecase->out_snd_device;
+ }
}
if (usecase->type == PCM_PLAYBACK) {
usecase->devices = usecase->stream.out->devices;
@@ -677,7 +656,6 @@
*/
if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL) {
status = platform_switch_voice_call_device_pre(adev->platform);
- disable_all_usecases_of_type(adev, VOICE_CALL, true);
}
/* Disable current sound devices */
@@ -713,10 +691,7 @@
usecase->in_snd_device = in_snd_device;
usecase->out_snd_device = out_snd_device;
- if (usecase->type == VOICE_CALL || usecase->type == VOIP_CALL)
- enable_all_usecases_of_type(adev, usecase->type, true);
- else
- enable_audio_route(adev, usecase, true);
+ enable_audio_route(adev, usecase, true);
/* Applicable only on the targets that has external modem.
* Enable device command should be sent to modem only after
@@ -1355,14 +1330,14 @@
struct listnode *node;
struct str_parms *parms;
char value[32];
- int ret, val = 0;
+ int ret = 0, val = 0, err;
bool select_new_device = false;
ALOGD("%s: enter: usecase(%d: %s) kvpairs: %s",
__func__, out->usecase, use_case_table[out->usecase], kvpairs);
parms = str_parms_create_str(kvpairs);
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
- if (ret >= 0) {
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
+ if (err >= 0) {
val = atoi(value);
pthread_mutex_lock(&out->lock);
pthread_mutex_lock(&adev->lock);
@@ -1406,18 +1381,18 @@
if ((adev->mode == AUDIO_MODE_IN_CALL) &&
!voice_is_in_call(adev) &&
(out == adev->primary_output)) {
- voice_start_call(adev);
+ ret = voice_start_call(adev);
} else if ((adev->mode == AUDIO_MODE_IN_CALL) &&
voice_is_in_call(adev) &&
(out == adev->primary_output)) {
- select_devices(adev, get_voice_usecase_id_from_list(adev));
+ update_devices_for_all_voice_usecases(adev);
}
}
if ((adev->mode == AUDIO_MODE_NORMAL) &&
voice_is_in_call(adev) &&
(out == adev->primary_output)) {
- voice_stop_call(adev);
+ ret = voice_stop_call(adev);
}
pthread_mutex_unlock(&adev->lock);
@@ -1837,16 +1812,16 @@
struct str_parms *parms;
char *str;
char value[32];
- int ret, val = 0;
+ int ret = 0, val = 0, err;
ALOGV("%s: enter: kvpairs=%s", __func__, kvpairs);
parms = str_parms_create_str(kvpairs);
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
-
pthread_mutex_lock(&in->lock);
pthread_mutex_lock(&adev->lock);
- if (ret >= 0) {
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
+ if (err >= 0) {
val = atoi(value);
/* no audio source uses val == 0 */
if ((in->source != val) && (val != 0)) {
@@ -1854,8 +1829,8 @@
}
}
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
- if (ret >= 0) {
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
+ if (err >= 0) {
val = atoi(value);
if ((in->device != val) && (val != 0)) {
in->device = val;
@@ -2008,7 +1983,7 @@
{
struct audio_device *adev = (struct audio_device *)dev;
struct stream_out *out;
- int i, ret;
+ int i, ret = 0;
ALOGV("%s: enter: sample_rate(%d) channel_mask(%#x) devices(%#x) flags(%#x)",
__func__, config->sample_rate, config->channel_mask, devices, flags);
@@ -2138,6 +2113,9 @@
}
}
+ //Decide if we need to use gapless mode by default
+ set_gapless_mode(adev);
+
} else if (out->flags & AUDIO_OUTPUT_FLAG_INCALL_MUSIC) {
ret = voice_check_and_set_incall_music_usecase(adev, out);
if (ret != 0) {
@@ -2252,18 +2230,23 @@
char *str;
char value[32];
int val;
- int ret;
+ int ret = 0, err;
ALOGD("%s: enter: %s", __func__, kvpairs);
pthread_mutex_lock(&adev->lock);
parms = str_parms_create_str(kvpairs);
- voice_set_parameters(adev, parms);
- platform_set_parameters(adev->platform, parms);
+ ret = voice_set_parameters(adev, parms);
+ if (ret != 0)
+ goto done;
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
- if (ret >= 0) {
+ ret = platform_set_parameters(adev->platform, parms);
+ if (ret != 0)
+ goto done;
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_BT_NREC, value, sizeof(value));
+ if (err >= 0) {
/* When set to false, HAL should disable EC and NS
* But it is currently not supported.
*/
@@ -2273,16 +2256,16 @@
adev->bluetooth_nrec = false;
}
- ret = str_parms_get_str(parms, "screen_state", value, sizeof(value));
- if (ret >= 0) {
+ err = str_parms_get_str(parms, "screen_state", value, sizeof(value));
+ if (err >= 0) {
if (strcmp(value, AUDIO_PARAMETER_VALUE_ON) == 0)
adev->screen_off = false;
else
adev->screen_off = true;
}
- ret = str_parms_get_int(parms, "rotation", &val);
- if (ret >= 0) {
+ err = str_parms_get_int(parms, "rotation", &val);
+ if (err >= 0) {
bool reverse_speakers = false;
switch(val) {
// FIXME: note that the code below assumes that the speakers are in the correct placement
@@ -2314,8 +2297,9 @@
}
audio_extn_set_parameters(adev, parms);
- str_parms_destroy(parms);
+done:
+ str_parms_destroy(parms);
pthread_mutex_unlock(&adev->lock);
ALOGV("%s: exit with code(%d)", __func__, ret);
return ret;
@@ -2332,7 +2316,7 @@
pthread_mutex_lock(&adev->lock);
audio_extn_get_parameters(adev, query, reply);
- voice_extn_get_parameters(adev, query, reply);
+ voice_get_parameters(adev, query, reply);
platform_get_parameters(adev->platform, query, reply);
str = str_parms_to_str(reply);
str_parms_destroy(query);
@@ -2688,6 +2672,33 @@
return fragment_size;
}
+static int set_gapless_mode(struct audio_device *adev) {
+
+
+ char value[PROPERTY_VALUE_MAX] = {0};
+ bool gapless_enabled = false;
+ const char *mixer_ctl_name = "Compress Gapless Playback";
+ struct mixer_ctl *ctl;
+
+ ALOGV("%s:", __func__);
+ property_get("audio.offload.gapless.enabled", value, NULL);
+ gapless_enabled = atoi(value) || !strncmp("true", value, 4);
+
+ ctl = mixer_get_ctl_by_name(adev->mixer, mixer_ctl_name);
+ if (!ctl) {
+ ALOGE("%s: Could not get ctl for mixer cmd - %s",
+ __func__, mixer_ctl_name);
+ return -EINVAL;
+ }
+
+ if (mixer_ctl_set_value(ctl, 0, gapless_enabled) < 0) {
+ ALOGE("%s: Could not set gapless mode %d",
+ __func__, gapless_enabled);
+ return -EINVAL;
+ }
+ return 0;
+
+}
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open,
};
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index ff9aeaa..807ede4 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -871,6 +871,36 @@
goto exit;
}
+ if (popcount(devices) == 2) {
+ if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
+ AUDIO_DEVICE_OUT_SPEAKER)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
+ } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
+ AUDIO_DEVICE_OUT_SPEAKER)) {
+ if (audio_extn_get_anc_enabled())
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET;
+ else
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
+ } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
+ AUDIO_DEVICE_OUT_SPEAKER)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
+ } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
+ AUDIO_DEVICE_OUT_SPEAKER)) {
+ snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
+ } else {
+ ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
+ goto exit;
+ }
+ if (snd_device != SND_DEVICE_NONE) {
+ goto exit;
+ }
+ }
+
+ if (popcount(devices) != 1) {
+ ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
+ goto exit;
+ }
+
if ((mode == AUDIO_MODE_IN_CALL) ||
voice_extn_compress_voip_is_active(adev)) {
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
@@ -922,36 +952,6 @@
}
}
- if (popcount(devices) == 2) {
- if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
- } else if (devices == (AUDIO_DEVICE_OUT_WIRED_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- if (audio_extn_get_anc_enabled())
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_ANC_HEADSET;
- else
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES;
- } else if (devices == (AUDIO_DEVICE_OUT_AUX_DIGITAL |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_HDMI;
- } else if (devices == (AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
- AUDIO_DEVICE_OUT_SPEAKER)) {
- snd_device = SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET;
- } else {
- ALOGE("%s: Invalid combo device(%#x)", __func__, devices);
- goto exit;
- }
- if (snd_device != SND_DEVICE_NONE) {
- goto exit;
- }
- }
-
- if (popcount(devices) != 1) {
- ALOGE("%s: Invalid output devices(%#x)", __func__, devices);
- goto exit;
- }
-
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
devices & AUDIO_DEVICE_OUT_WIRED_HEADSET) {
if (devices & AUDIO_DEVICE_OUT_WIRED_HEADSET
@@ -1359,12 +1359,12 @@
char *str;
char value[256] = {0};
int val;
- int ret = 0;
+ int ret = 0, err;
ALOGV("%s: enter: %s", __func__, str_parms_to_str(parms));
- ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_BTSCO, &val);
- if (ret >= 0) {
+ err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_BTSCO, &val);
+ if (err >= 0) {
str_parms_del(parms, AUDIO_PARAMETER_KEY_BTSCO);
my_data->btsco_sample_rate = val;
if (val == SAMPLE_RATE_16KHZ) {
@@ -1374,8 +1374,8 @@
}
}
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value));
- if (ret >= 0) {
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_SLOWTALK, value, sizeof(value));
+ if (err >= 0) {
bool state = false;
if (!strncmp("true", value, sizeof("true"))) {
state = true;
@@ -1387,9 +1387,9 @@
ALOGE("%s: Failed to set slow talk err: %d", __func__, ret);
}
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST,
value, sizeof(value));
- if (ret >= 0) {
+ if (err >= 0) {
str_parms_del(parms, AUDIO_PARAMETER_KEY_VOLUME_BOOST);
if (my_data->acdb_reload_vocvoltable == NULL) {
diff --git a/hal/voice.c b/hal/voice.c
index cbf8956..74d1978 100644
--- a/hal/voice.c
+++ b/hal/voice.c
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a contribution.
*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -351,20 +351,32 @@
return ret;
}
+void voice_get_parameters(struct audio_device *adev,
+ struct str_parms *query,
+ struct str_parms *reply)
+{
+ voice_extn_get_parameters(adev, query, reply);
+}
+
int voice_set_parameters(struct audio_device *adev, struct str_parms *parms)
{
char *str;
char value[32];
int val;
- int ret = 0;
+ int ret = 0, err;
ALOGV("%s: enter: %s", __func__, str_parms_to_str(parms));
- voice_extn_set_parameters(adev, parms);
- voice_extn_compress_voip_set_parameters(adev, parms);
+ ret = voice_extn_set_parameters(adev, parms);
+ if (ret != 0)
+ goto done;
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
- if (ret >= 0) {
+ ret = voice_extn_compress_voip_set_parameters(adev, parms);
+ if (ret != 0)
+ goto done;
+
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_TTY_MODE, value, sizeof(value));
+ if (err >= 0) {
int tty_mode;
str_parms_del(parms, AUDIO_PARAMETER_KEY_TTY_MODE);
if (strcmp(value, AUDIO_PARAMETER_VALUE_TTY_OFF) == 0)
@@ -389,9 +401,9 @@
}
}
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC,
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC,
value, sizeof(value));
- if (ret >= 0) {
+ if (err >= 0) {
str_parms_del(parms, AUDIO_PARAMETER_KEY_INCALLMUSIC);
if (strcmp(value, AUDIO_PARAMETER_VALUE_TRUE) == 0)
platform_start_incall_music_usecase(adev->platform);
diff --git a/hal/voice.h b/hal/voice.h
index eeb65dc..38b304e 100644
--- a/hal/voice.h
+++ b/hal/voice.h
@@ -72,6 +72,8 @@
int voice_start_call(struct audio_device *adev);
int voice_stop_call(struct audio_device *adev);
int voice_set_parameters(struct audio_device *adev, struct str_parms *parms);
+void voice_get_parameters(struct audio_device *adev, struct str_parms *query,
+ struct str_parms *reply);
void voice_init(struct audio_device *adev);
bool voice_is_in_call(struct audio_device *adev);
int voice_set_mic_mute(struct audio_device *dev, bool state);
diff --git a/hal/voice_extn/compress_voip.c b/hal/voice_extn/compress_voip.c
index ee9fd30..d119ff5 100644
--- a/hal/voice_extn/compress_voip.c
+++ b/hal/voice_extn/compress_voip.c
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a contribution.
*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -400,53 +400,57 @@
return ret;
}
-void voice_extn_compress_voip_set_parameters(struct audio_device *adev,
+int voice_extn_compress_voip_set_parameters(struct audio_device *adev,
struct str_parms *parms)
{
char *str;
char value[32]={0};
- int ret, rate;
+ int ret = 0, err, rate;
int min_rate, max_rate;
bool flag;
ALOGV("%s: enter: %s", __func__, str_parms_to_str(parms));
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_RATE,
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_RATE,
value, sizeof(value));
- if (ret >= 0) {
+ if (err >= 0) {
rate = atoi(value);
voip_set_rate(adev, rate);
voip_set_evrc_min_max_rate(adev, rate, rate);
}
memset(value, 0, sizeof(value));
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_EVRC_RATE_MIN,
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_EVRC_RATE_MIN,
value, sizeof(value));
- if (ret >= 0) {
+ if (err >= 0) {
min_rate = atoi(value);
str_parms_del(parms, AUDIO_PARAMETER_KEY_VOIP_EVRC_RATE_MIN);
memset(value, 0, sizeof(value));
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_EVRC_RATE_MAX,
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_EVRC_RATE_MAX,
value, sizeof(value));
- if (ret >= 0) {
+ if (err >= 0) {
max_rate = atoi(value);
voip_set_evrc_min_max_rate(adev, min_rate, max_rate);
- }
- else
+ } else {
ALOGE("%s: AUDIO_PARAMETER_KEY_VOIP_EVRC_RATE_MAX not found", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
}
memset(value, 0, sizeof(value));
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_DTX_MODE,
+ err = str_parms_get_str(parms, AUDIO_PARAMETER_KEY_VOIP_DTX_MODE,
value, sizeof(value));
- if (ret >= 0) {
+ if (err >= 0) {
flag = false;
if (strcmp(value, AUDIO_PARAMETER_VALUE_VOIP_TRUE) == 0)
flag = true;
voip_set_dtx(adev, flag);
}
+done:
ALOGV("%s: exit", __func__);
+ return ret;
}
void voice_extn_compress_voip_out_get_parameters(struct stream_out *out,
diff --git a/hal/voice_extn/voice_extn.c b/hal/voice_extn/voice_extn.c
index 989a871..12fce09 100644
--- a/hal/voice_extn/voice_extn.c
+++ b/hal/voice_extn/voice_extn.c
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a contribution.
*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,8 +34,12 @@
#include "platform_api.h"
#include "voice_extn.h"
-#define AUDIO_PARAMETER_KEY_VSID "vsid"
-#define AUDIO_PARAMETER_KEY_CALL_STATE "call_state"
+#define AUDIO_PARAMETER_KEY_VSID "vsid"
+#define AUDIO_PARAMETER_KEY_CALL_STATE "call_state"
+#define AUDIO_PARAMETER_KEY_AUDIO_MODE "audio_mode"
+#define AUDIO_PARAMETER_KEY_ALL_CALL_STATES "all_call_states"
+
+#define VOICE_EXTN_PARAMETER_VALUE_MAX_LEN 256
#define VOICE2_VSID 0x10DC1000
#define VOLTE_VSID 0x10C02000
@@ -405,17 +409,17 @@
{
char *str;
int value;
- int ret = 0;
+ int ret = 0, err;
ALOGV("%s: enter: %s", __func__, str_parms_to_str(parms));
- ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_VSID, &value);
- if (ret >= 0) {
+ err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_VSID, &value);
+ if (err >= 0) {
str_parms_del(parms, AUDIO_PARAMETER_KEY_VSID);
- int vsid = value;
+ uint32_t vsid = value;
int call_state = -1;
- ret = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_CALL_STATE, &value);
- if (ret >= 0) {
+ err = str_parms_get_int(parms, AUDIO_PARAMETER_KEY_CALL_STATE, &value);
+ if (err >= 0) {
call_state = value;
} else {
ALOGE("%s: call_state key not found", __func__);
@@ -432,7 +436,7 @@
goto done;
}
} else {
- ALOGD("%s: Not handled here", __func__);
+ ALOGV("%s: Not handled here", __func__);
}
done:
@@ -440,21 +444,51 @@
return ret;
}
+int get_all_call_states_str(const struct audio_device *adev,
+ char *value)
+{
+ int ret = 0;
+ char *cur_ptr = value;
+ int i, len=0;
+
+ for (i = 0; i < MAX_VOICE_SESSIONS; i++) {
+ snprintf(cur_ptr, VOICE_EXTN_PARAMETER_VALUE_MAX_LEN - len,
+ "%d:%d,",adev->voice.session[i].vsid,
+ adev->voice.session[i].state.current);
+ len = strlen(cur_ptr);
+ cur_ptr = cur_ptr + len;
+ }
+ ALOGV("%s:value=%s", __func__, value);
+ return ret;
+}
+
void voice_extn_get_parameters(const struct audio_device *adev,
struct str_parms *query,
struct str_parms *reply)
{
int ret;
- char value[32]={0};
+ char value[VOICE_EXTN_PARAMETER_VALUE_MAX_LEN] = {0};
char *str = NULL;
- ret = str_parms_get_str(query, "audio_mode", value,
+ ALOGV("%s: enter %s", __func__, str_parms_to_str(query));
+
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_AUDIO_MODE, value,
sizeof(value));
if (ret >= 0) {
- str_parms_add_int(reply, "audio_mode", adev->mode);
+ str_parms_add_int(reply, AUDIO_PARAMETER_KEY_AUDIO_MODE, adev->mode);
}
- ALOGV("%s: returns %s", __func__, str_parms_to_str(reply));
+ ret = str_parms_get_str(query, AUDIO_PARAMETER_KEY_ALL_CALL_STATES,
+ value, sizeof(value));
+ if (ret >= 0) {
+ ret = get_all_call_states_str(adev, value);
+ if (ret) {
+ ALOGE("%s: Error fetching call states, err:%d", __func__, ret);
+ return;
+ }
+ str_parms_add_str(reply, AUDIO_PARAMETER_KEY_ALL_CALL_STATES, value);
+ }
+ ALOGV("%s: exit: returns \"%s\"", __func__, str_parms_to_str(reply));
}
void voice_extn_out_get_parameters(struct stream_out *out,
diff --git a/hal/voice_extn/voice_extn.h b/hal/voice_extn/voice_extn.h
index 0ca2386..adee939 100644
--- a/hal/voice_extn/voice_extn.h
+++ b/hal/voice_extn/voice_extn.h
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a contribution.
*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2013-2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -128,7 +128,7 @@
int voice_extn_compress_voip_select_devices(struct audio_device *adev,
snd_device_t *out_snd_device,
snd_device_t *in_snd_device);
-void voice_extn_compress_voip_set_parameters(struct audio_device *adev,
+int voice_extn_compress_voip_set_parameters(struct audio_device *adev,
struct str_parms *parms);
void voice_extn_compress_voip_out_get_parameters(struct stream_out *out,
@@ -210,10 +210,11 @@
return -ENOSYS;
}
-static void voice_extn_compress_voip_set_parameters(struct audio_device *adev,
+static int voice_extn_compress_voip_set_parameters(struct audio_device *adev,
struct str_parms *parms)
{
ALOGE("%s: COMPRESS_VOIP_ENABLED is not defined", __func__);
+ return -ENOSYS;
}
static void voice_extn_compress_voip_out_get_parameters(struct stream_out *out,
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index d44a251..f64bbfe 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2009 The Android Open Source Project
@@ -590,7 +590,7 @@
case STRATEGY_MEDIA: {
uint32_t device2 = AUDIO_DEVICE_NONE;
- if (isInCall()) {
+ if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
// when in call, get the device for Phone strategy
device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
break;