Merge "st-hal: Add feature flag for daemon support"
diff --git a/sound_trigger_hw.c b/sound_trigger_hw.c
index 74ac639..3073a17 100644
--- a/sound_trigger_hw.c
+++ b/sound_trigger_hw.c
@@ -793,6 +793,21 @@
if (!num_sessions) {
stdev->session_allowed = conc_allowed;
+ /*
+ * This is needed for the following usecase:
+ *
+ * 1. LPI and NLPI have different number of MICs (different devices).
+ * 2. ST session is stopped from app and unloaded while Tx active.
+ * 3. Tx stops.
+ * 4. ST session started again from app on LPI.
+ *
+ * The device disablement is missed in step 3 because the st_session was
+ * deinitialized. Thus, it is handled here.
+ */
+ if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE &&
+ !platform_stdev_is_dedicated_sva_path(stdev->platform) &&
+ platform_stdev_backend_reset_allowed(stdev->platform))
+ platform_stdev_disable_stale_devices(stdev->platform);
pthread_mutex_unlock(&stdev->lock);
return;
}
@@ -849,12 +864,26 @@
}
} else {
if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
+ /*
+ * The reset_backend flag allows the backend device to be disabled. This should
+ * only be disallowed when in non-dedicated path mode and there is an active
+ * audio input stream.
+ */
+ stdev->reset_backend = platform_stdev_backend_reset_allowed(stdev->platform);
+ st_hw_check_and_update_lpi(stdev, p_ses);
+ stdev->vad_enable = st_hw_check_vad_support(stdev, p_ses, stdev->lpi_enable);
+
list_for_each(p_ses_node, &stdev->sound_model_list) {
p_ses = node_to_item(p_ses_node, st_session_t, list_node);
ALOGD("%s:[%d] Capture device is disabled, pause SVA session",
__func__, p_ses->sm_handle);
st_session_pause(p_ses);
}
+ /*
+ * This is needed when the session goes to loaded state, then
+ * LPI/NLPI switch happens due to Rx event.
+ */
+ platform_stdev_disable_stale_devices(stdev->platform);
list_for_each(p_ses_node, &stdev->sound_model_list) {
p_ses = node_to_item(p_ses_node, st_session_t, list_node);
ALOGD("%s:[%d] Capture device is disabled, resume SVA session",
@@ -922,6 +951,15 @@
}
}
}
+ /*
+ * The device can be disabled within this thread upon reception of the device
+ * active event because audio hal does not enable the device until after returning
+ * from this callback. After this thread exits, device disablement will be
+ * disallowed until the device inactive event is received.
+ */
+ if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE &&
+ !platform_stdev_is_dedicated_sva_path(stdev->platform))
+ stdev->reset_backend = platform_stdev_backend_reset_allowed(stdev->platform);
pthread_mutex_unlock(&stdev->lock);
ALOGV("%s: Exit", __func__);
}
@@ -1069,6 +1107,7 @@
st_session_disable_device(p_ses);
}
sthw_extn_lpma_notify_event(LPMA_EVENT_DISABLE_DEVICE);
+ platform_stdev_disable_stale_devices(stdev->platform);
list_for_each(p_ses_node, &stdev->sound_model_list) {
p_ses = node_to_item(p_ses_node, st_session_t, list_node);
@@ -1264,16 +1303,9 @@
pthread_mutex_unlock(&stdev->lock);
}
-static int stdev_get_properties(const struct sound_trigger_hw_device *dev,
- struct sound_trigger_properties *properties)
+static void get_base_properties(struct sound_trigger_device *stdev)
{
- struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;
-
- ALOGI("%s", __func__);
- if (properties == NULL) {
- ALOGE("%s: NULL properties", __func__);
- return -EINVAL;
- }
+ ALOGI("%s: enter", __func__);
stdev->hw_properties->concurrent_capture = stdev->conc_capture_supported;
@@ -1301,8 +1333,24 @@
stdev->hw_properties->capture_transition,
stdev->hw_properties->concurrent_capture);
- memcpy(properties, stdev->hw_properties,
+ memset(&hw_properties_extended, 0, sizeof(hw_properties_extended));
+ memcpy(&hw_properties_extended.base, stdev->hw_properties,
sizeof(struct sound_trigger_properties));
+}
+
+static int stdev_get_properties(const struct sound_trigger_hw_device *dev,
+ struct sound_trigger_properties *properties)
+{
+ struct sound_trigger_device *stdev = (struct sound_trigger_device *)dev;
+
+ ALOGI("%s", __func__);
+ if (properties == NULL) {
+ ALOGE("%s: NULL properties", __func__);
+ return -EINVAL;
+ }
+
+ get_base_properties(stdev);
+ memcpy(properties, &hw_properties_extended.base, sizeof(struct sound_trigger_properties));
hw_properties_extended.header.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_0;
return 0;
}
@@ -1510,8 +1558,8 @@
static bool compare_recognition_config
(
- const struct sound_trigger_recognition_config *current_config,
- struct sound_trigger_recognition_config *new_config
+ const struct sound_trigger_recognition_config *new_config,
+ struct sound_trigger_recognition_config *current_config
)
{
unsigned int i = 0, j = 0;
@@ -1533,7 +1581,6 @@
(current_config->capture_requested != new_config->capture_requested) ||
(current_config->num_phrases != new_config->num_phrases) ||
(current_config->data_size != new_config->data_size) ||
- (current_config->data_offset != new_config->data_offset) ||
(hw_properties_extended.header.version == SOUND_TRIGGER_DEVICE_API_VERSION_1_3 &&
memcmp((char *) current_config + current_config->data_offset,
(char *) new_config + sizeof(struct sound_trigger_recognition_config) +
@@ -2739,11 +2786,8 @@
stdev = (struct sound_trigger_device *)dev;
prop_hdr = (struct sound_trigger_properties_header *)&hw_properties_extended;
- status = stdev_get_properties(dev, &hw_properties_extended.base);
- if (status) {
- ALOGW("%s: Failed to initialize the stdev properties", __func__);
- return NULL;
- }
+ get_base_properties(stdev);
+
hw_properties_extended.header.size = sizeof(struct sound_trigger_properties_extended_1_3);
hw_properties_extended.audio_capabilities = 0;
hw_properties_extended.header.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;
@@ -2772,7 +2816,7 @@
goto exit_2;
}
- st_session->f_stage_version = ST_MODULE_TYPE_CUSTOM;
+ st_session->f_stage_version = ST_MODULE_TYPE_GMM;
st_session->vendor_uuid_info = v_info;
handle = android_atomic_inc(&stdev->session_id);
@@ -2953,7 +2997,13 @@
stdev_ref_cnt++;
pthread_mutex_unlock(&stdev_init_lock);
+ get_base_properties(stdev);
+ hw_properties_extended.header.size = sizeof(struct sound_trigger_properties_extended_1_3);
+ hw_properties_extended.audio_capabilities = 0;
+ hw_properties_extended.header.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;
+
ATRACE_END();
+ ALOGD("%s: Exit ", __func__);
return 0;
exit_1:
@@ -3290,6 +3340,15 @@
handle_screen_status_change(config);
break;
+ case AUDIO_EVENT_ROUTE_INIT_DONE:
+ if (!config) {
+ ALOGE("%s: NULL config for AUDIO_EVENT_ROUTE_INIT_DONE", __func__);
+ ret = -EINVAL;
+ break;
+ }
+ stdev->audio_route = config->u.audio_route;
+ break;
+
default:
ALOGW("%s: Unknown event %d", __func__, event);
break;
diff --git a/sound_trigger_hw.h b/sound_trigger_hw.h
index 85b33eb..01feae9 100644
--- a/sound_trigger_hw.h
+++ b/sound_trigger_hw.h
@@ -261,6 +261,7 @@
bool screen_off;
bool barge_in_mode;
int ec_reset_pending_cnt;
+ bool shared_mixer;
};
typedef struct sound_trigger_device sound_trigger_device_t;
diff --git a/sound_trigger_platform.c b/sound_trigger_platform.c
old mode 100644
new mode 100755
index cefc47e..3a0f668
--- a/sound_trigger_platform.c
+++ b/sound_trigger_platform.c
@@ -59,6 +59,7 @@
#include <cutils/str_parms.h>
#include <cutils/properties.h>
#include <cutils/trace.h>
+#include <cutils/bitops.h>
#include <dlfcn.h>
#include <expat.h>
#include <errno.h>
@@ -2541,8 +2542,7 @@
return -ENOMEM;
}
- if (my_data->xml_version > PLATFORM_XML_VERSION_0x0105)
- list_init(&lsm_params->module_params_list);
+ list_init(&lsm_params->module_params_list);
list_add_tail(&sm_info->lsm_usecase_list, &lsm_params->list_node);
@@ -3797,6 +3797,22 @@
return true;
}
+bool platform_stdev_backend_reset_allowed
+(
+ void *platform
+)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ sound_trigger_device_t *stdev = my_data->stdev;
+
+ if (stdev->conc_capture_supported &&
+ stdev->tx_concurrency_active > 0 &&
+ !platform_stdev_is_dedicated_sva_path(platform))
+ return false;
+ else
+ return true;
+}
+
static int platform_stdev_get_device_sample_rate
(
struct platform_data *my_data,
@@ -4097,12 +4113,16 @@
snd_card_name = mixer_get_name(stdev->mixer);
- query_stdev_platform(my_data, snd_card_name, mixer_path_xml);
- stdev->audio_route = audio_route_init(snd_card_num, mixer_path_xml);
- if (!stdev->audio_route) {
- ALOGE("%s: ERROR. Failed to init audio route controls, aborting.",
- __func__);
- goto cleanup;
+ stdev->shared_mixer =
+ property_get_bool("persist.vendor.audio.shared_mixer.enabled", false);
+ if (!stdev->shared_mixer) {
+ query_stdev_platform(my_data, snd_card_name, mixer_path_xml);
+ stdev->audio_route = audio_route_init(snd_card_num, mixer_path_xml);
+ if (!stdev->audio_route) {
+ ALOGE("%s: ERROR. Failed to init audio route controls, aborting.",
+ __func__);
+ goto cleanup;
+ }
}
stdev->snd_card = snd_card_num;
@@ -5005,8 +5025,8 @@
if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
/* handle CAPTURE_DEVICE events */
- ALOGI("%s: Received DEVICE event, event type %d",
- __func__, event_type);
+ ALOGI("%s: Received DEVICE event, event type %d, usecase type %d",
+ __func__, event_type, config->u.usecase.type);
/*
* for device status events, if:
* 1. conc audio disabled - return with false to disable VA sessions
@@ -5016,56 +5036,70 @@
switch (event_type) {
case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
stdev->tx_concurrency_active++;
+ switch (config->u.usecase.type) {
+ case USECASE_TYPE_VOICE_CALL:
+ stdev->conc_voice_active = true;
+ break;
+ case USECASE_TYPE_VOIP_CALL:
+ stdev->conc_voip_active = true;
+ break;
+ default:
+ break;
+ }
break;
case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
if (stdev->tx_concurrency_active > 0)
stdev->tx_concurrency_active--;
+ switch (config->u.usecase.type) {
+ case USECASE_TYPE_VOICE_CALL:
+ stdev->conc_voice_active = false;
+ break;
+ case USECASE_TYPE_VOIP_CALL:
+ stdev->conc_voip_active = false;
+ break;
+ default:
+ break;
+ }
break;
default:
break;
}
- if (stdev->conc_capture_supported)
- concurrency_ses_allowed = stdev->session_allowed;
- else if (stdev->tx_concurrency_active > 0)
+
+ /*
+ * This disablement of VOIP/Voice flags is needed for the following usecase:
+ *
+ * 1. VOIP/Voice and AR active.
+ * 2. VOIP/Voice stops - AHAL sends stream inactive events for each stream,
+ * followed by the shared device inactive and device active events which
+ * both have VOIP/voice usecase, followed by one stream active event for AR.
+ * 3. AR stops - stream and device inactive events with pcm capture usecase.
+ *
+ * In this usecase the VOIP/voice flags get stuck set to true, so reset them here.
+ */
+ if (stdev->tx_concurrency_active == 0) {
+ stdev->conc_voice_active = false;
+ stdev->conc_voip_active = false;
+ }
+ if ((!stdev->conc_capture_supported &&
+ stdev->tx_concurrency_active > 0) ||
+ (stdev->conc_capture_supported &&
+ ((!stdev->conc_voice_call_supported && stdev->conc_voice_active) ||
+ (!stdev->conc_voip_call_supported && stdev->conc_voip_active))))
concurrency_ses_allowed = false;
} else {
/* handle CAPTURE_STREAM events */
ALOGI("%s: Received STREAM event, event type %d, usecase type %d",
__func__, event_type, config->u.usecase.type);
switch (event_type) {
- case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
- switch (config->u.usecase.type) {
- case USECASE_TYPE_VOICE_CALL:
- stdev->conc_voice_active = true;
- break;
- case USECASE_TYPE_VOIP_CALL:
- stdev->conc_voip_active = true;
- break;
- default:
- break;
- }
- break;
- case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
- switch (config->u.usecase.type) {
- case USECASE_TYPE_VOICE_CALL:
- stdev->conc_voice_active = false;
- break;
- case USECASE_TYPE_VOIP_CALL:
- stdev->conc_voip_active = false;
- break;
- default:
- break;
- }
- break;
- case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
- stdev->rx_concurrency_active++;
- break;
- case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
- if (stdev->rx_concurrency_active > 0)
- stdev->rx_concurrency_active--;
- break;
- default:
- break;
+ case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
+ stdev->rx_concurrency_active++;
+ break;
+ case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
+ if (stdev->rx_concurrency_active > 0)
+ stdev->rx_concurrency_active--;
+ break;
+ default:
+ break;
}
if (event_type == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE ||
event_type == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
@@ -5074,27 +5108,10 @@
num_sessions > stdev->rx_conc_max_st_ses)
concurrency_ses_allowed = false;
}
- if (concurrency_ses_allowed) {
- if ((!stdev->conc_capture_supported &&
- stdev->tx_concurrency_active > 0) ||
- (stdev->conc_capture_supported &&
- ((!stdev->conc_voice_call_supported && stdev->conc_voice_active) ||
- (!stdev->conc_voip_call_supported && stdev->conc_voip_active))))
- concurrency_ses_allowed = false;
- }
+ if (concurrency_ses_allowed)
+ concurrency_ses_allowed = stdev->session_allowed;
}
- /*
- * Mark reset_backend as false to prevent disabling tx
- * device when pausing VA sessions.
- */
- if (stdev->conc_capture_supported &&
- stdev->tx_concurrency_active > 0 &&
- (!platform_stdev_is_dedicated_sva_path(stdev->platform)))
- stdev->reset_backend = false;
- else
- stdev->reset_backend = true;
-
ALOGD("%s: dedicated path %d, reset backend %d, tx %d, rx %d,"
" concurrency session%s allowed",
__func__, platform_stdev_is_dedicated_sva_path(stdev->platform),
@@ -5893,6 +5910,45 @@
return app_type;
}
+void platform_stdev_disable_stale_devices
+(
+ void *platform
+)
+{
+ struct platform_data *my_data = (struct platform_data *)platform;
+ sound_trigger_device_t *stdev = my_data->stdev;
+ char st_device_name[DEVICE_NAME_MAX_SIZE] = {0};
+
+ /*
+ * There can be stale devices while exec_mode is NONE with the
+ * below usecase:
+ *
+ * 1. SVA is active in non-dedicated path mode.
+ * 2. Tx starts, transitioning SVA to NLPI.
+ * 3. SVA stops and unloads, but cannot disable the BE device.
+ * 4. Tx stops - this function will get called with exec_mode NONE.
+ */
+ if (stdev->exec_mode == ST_EXEC_MODE_ADSP ||
+ (stdev->exec_mode == ST_EXEC_MODE_NONE &&
+ !stdev->is_gcs)) {
+ pthread_mutex_lock(&stdev->ref_cnt_lock);
+ for (int i = ST_DEVICE_MIN; i < ST_DEVICE_MAX; i++) {
+ if (0 < stdev->dev_enable_cnt[i]) {
+ platform_stdev_get_device_name(stdev->platform,
+ ST_EXEC_MODE_ADSP, i, st_device_name);
+ ALOGD("%s: disable device (%x) = %s", __func__, i,
+ st_device_name);
+ ATRACE_BEGIN("sthal: audio_route_reset_and_update_path");
+ audio_route_reset_and_update_path(stdev->audio_route,
+ st_device_name);
+ ATRACE_END();
+ --(stdev->dev_enable_cnt[i]);
+ }
+ }
+ pthread_mutex_unlock(&stdev->ref_cnt_lock);
+ }
+}
+
static void check_and_append_ec_ref_device_name
(
void *platform,
@@ -5957,11 +6013,12 @@
struct platform_data *my_data = (struct platform_data *)platform;
sound_trigger_device_t *stdev = my_data->stdev;
struct sound_trigger_event_info event_info = {{0}, 0};
+ bool force_reset_ec = stdev->shared_mixer;
if (is_ec_profile(profile_type)) {
event_info.st_ec_ref_enabled = enable;
// reset the pending active EC mixer ctls first
- if (!stdev->audio_ec_enabled) {
+ if (!stdev->audio_ec_enabled && !force_reset_ec) {
while (stdev->ec_reset_pending_cnt > 0) {
audio_route_reset_and_update_path(stdev->audio_route,
my_data->ec_ref_mixer_path);
@@ -5982,7 +6039,7 @@
} else {
stdev->audio_hal_cb(ST_EVENT_UPDATE_ECHO_REF, &event_info);
/* avoid disabling echo if audio hal has enabled echo ref */
- if (!stdev->audio_ec_enabled) {
+ if (!stdev->audio_ec_enabled || force_reset_ec) {
ALOGD("%s: reset echo ref %s", __func__,
my_data->ec_ref_mixer_path);
audio_route_reset_and_update_path(stdev->audio_route,
diff --git a/sound_trigger_platform.h b/sound_trigger_platform.h
index d7e4277..1dad3b9 100755
--- a/sound_trigger_platform.h
+++ b/sound_trigger_platform.h
@@ -658,6 +658,11 @@
char *use_case
);
+void platform_stdev_disable_stale_devices
+(
+ void *platform
+);
+
void platform_stdev_check_and_update_ec_ref_config
(
void *platform,
@@ -717,6 +722,11 @@
void *platform
);
+bool platform_stdev_backend_reset_allowed
+(
+ void *platform
+);
+
int platform_stdev_derive_mixer_ctl_from_backend
(
void *platform,
diff --git a/sound_trigger_prop_intf.h b/sound_trigger_prop_intf.h
index 4cd599c..71b1e1b 100644
--- a/sound_trigger_prop_intf.h
+++ b/sound_trigger_prop_intf.h
@@ -73,7 +73,8 @@
AUDIO_EVENT_BATTERY_STATUS_CHANGED,
AUDIO_EVENT_GET_PARAM,
AUDIO_EVENT_UPDATE_ECHO_REF,
- AUDIO_EVENT_SCREEN_STATUS_CHANGED
+ AUDIO_EVENT_SCREEN_STATUS_CHANGED,
+ AUDIO_EVENT_ROUTE_INIT_DONE
};
typedef enum audio_event_type audio_event_type_t;
@@ -137,6 +138,7 @@
struct audio_hal_usecase usecase;
bool audio_ec_ref_enabled;
struct sound_trigger_get_param_data st_get_param_data;
+ struct audio_route *audio_route;
} u;
struct sound_trigger_device_info device_info;
};
diff --git a/st_hw_common.c b/st_hw_common.c
index 1255c43..97624cb 100644
--- a/st_hw_common.c
+++ b/st_hw_common.c
@@ -205,7 +205,8 @@
}
if (stdev->rx_concurrency_active || stdev->conc_voice_active ||
- stdev->conc_voip_active) {
+ stdev->conc_voip_active ||
+ !platform_stdev_backend_reset_allowed(stdev->platform)) {
ALOGD("%s: lpi NOT supported due to concurrency", __func__);
return;
}
diff --git a/st_session.c b/st_session.c
index 79268be..29bf304 100644
--- a/st_session.c
+++ b/st_session.c
@@ -184,7 +184,7 @@
lock_status = pthread_mutex_trylock(&st_ses->lock);
} while (lock_status && !st_ses->device_disabled &&
(st_ses->exec_mode != ST_EXEC_MODE_NONE) &&
- (st_ses->current_state != ssr_state_fn));
+ (st_ses->current_state == active_state_fn));
if (st_ses->device_disabled) {
ALOGV("%s:[%d] device switch in progress, ignore event",
@@ -192,8 +192,8 @@
} else if (st_ses->exec_mode == ST_EXEC_MODE_NONE) {
ALOGV("%s:[%d] transition in progress, ignore event",
__func__, st_ses->sm_handle);
- } else if (st_ses->current_state == ssr_state_fn) {
- ALOGV("%s:[%d] SSR handling in progress, ignore event",
+ } else if (st_ses->current_state != active_state_fn) {
+ ALOGV("%s:[%d] Session not in active state, ignore event",
__func__, st_ses->sm_handle);
} else if (!lock_status) {
/*
@@ -236,20 +236,23 @@
(st_ses->current_state == buffering_state_fn) &&
!st_ses->stdev->ssr_offline_received);
- if (st_ses->det_stc_ses->pending_stop)
+ if (st_ses->det_stc_ses->pending_stop) {
ALOGV("%s:[%d] pending stop already queued, ignore event",
__func__, st_ses->sm_handle);
- else if (!st_ses->det_stc_ses->detection_sent)
- ALOGV("%s:[%d] client callback hasn't been called, ignore event",
- __func__, st_ses->sm_handle);
- else if (st_ses->current_state != buffering_state_fn)
+ } else if (!st_ses->det_stc_ses->detection_sent) {
+ ev.ev_id = ST_SES_EV_RESTART;
+ DISPATCH_EVENT(st_ses, ev, status);
+ ALOGV("%s:[%d] client callback hasn't been called, restart detection evt_id(%d)",
+ __func__, st_ses->sm_handle, ev.ev_id);
+ } else if (st_ses->current_state != buffering_state_fn) {
ALOGV("%s:[%d] session already stopped buffering, ignore event",
__func__, st_ses->sm_handle);
- else if (st_ses->stdev->ssr_offline_received)
+ } else if (st_ses->stdev->ssr_offline_received) {
ALOGV("%s:[%d] SSR handling in progress, ignore event",
__func__, st_ses->sm_handle);
- else if (!lock_status)
+ } else if (!lock_status) {
DISPATCH_EVENT(st_ses, ev, status);
+ }
if (!lock_status)
pthread_mutex_unlock(&st_ses->lock);
@@ -5537,10 +5540,13 @@
break;
case ST_SES_EV_SET_DEVICE:
- if (!ev->payload.enable)
+ if (!ev->payload.enable) {
+ st_ses->device_disabled = true;
status = hw_ses->fptrs->disable_device(hw_ses, true);
- else
+ } else {
status = hw_ses->fptrs->enable_device(hw_ses, true);
+ st_ses->device_disabled = false;
+ }
if (status && st_ses->stdev->ssr_offline_received) {
STATE_TRANSITION(st_ses, ssr_state_fn);