hal: Add support for listen playback concurrency
Add support for concurrency handling between number of
listen capture session and playback activity.
Change-Id: I4a0656f240c62f2cc6266a714a96fdcdc13ae9d8
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index 965e93e..bab4563 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -152,18 +152,23 @@
#ifndef AUDIO_LISTEN_ENABLED
#define audio_extn_listen_init(adev, snd_card) (0)
#define audio_extn_listen_deinit(adev) (0)
-#define audio_extn_listen_update_status(uc_info, event) (0)
+#define audio_extn_listen_update_device_status(snd_dev, event) (0)
+#define audio_extn_listen_update_stream_status(uc_info, event) (0)
#define audio_extn_listen_set_parameters(adev, parms) (0)
#else
enum listen_event_type {
LISTEN_EVENT_SND_DEVICE_FREE,
- LISTEN_EVENT_SND_DEVICE_BUSY
+ LISTEN_EVENT_SND_DEVICE_BUSY,
+ LISTEN_EVENT_STREAM_FREE,
+ LISTEN_EVENT_STREAM_BUSY
};
typedef enum listen_event_type listen_event_type_t;
int audio_extn_listen_init(struct audio_device *adev, unsigned int snd_card);
void audio_extn_listen_deinit(struct audio_device *adev);
-void audio_extn_listen_update_status(snd_device_t snd_device,
+void audio_extn_listen_update_device_status(snd_device_t snd_device,
+ listen_event_type_t event);
+void audio_extn_listen_update_stream_status(struct audio_usecase *uc_info,
listen_event_type_t event);
void audio_extn_listen_set_parameters(struct audio_device *adev,
struct str_parms *parms);
diff --git a/hal/audio_extn/listen.c b/hal/audio_extn/listen.c
index 91bb04f..b1ed105 100644
--- a/hal/audio_extn/listen.c
+++ b/hal/audio_extn/listen.c
@@ -95,25 +95,75 @@
static struct listen_audio_device *listen_dev;
-void audio_extn_listen_update_status(snd_device_t snd_device,
- listen_event_type_t event)
+void audio_extn_listen_update_device_status(snd_device_t snd_device,
+ listen_event_type_t event)
{
- if (!platform_listen_update_status(snd_device)) {
- ALOGV("%s(): no need to notify listen. device = %s. Event = %u",
- __func__, platform_get_snd_device_name(snd_device), event);
+ bool raise_event = false;
+ int device_type = -1;
+
+ if (snd_device >= SND_DEVICE_OUT_BEGIN &&
+ snd_device < SND_DEVICE_OUT_END)
+ device_type = PCM_PLAYBACK;
+ else if (snd_device >= SND_DEVICE_IN_BEGIN &&
+ snd_device < SND_DEVICE_IN_END)
+ device_type = PCM_CAPTURE;
+ else {
+ ALOGE("%s: invalid device 0x%x, for event %d",
+ __func__, snd_device, event);
return;
}
if (listen_dev) {
- ALOGI("%s(): %s listen. current active device = %s. Event = %u",
- __func__,
- (event == LISTEN_EVENT_SND_DEVICE_BUSY) ? "stop" : "start",
- platform_get_snd_device_name(snd_device), event);
+ raise_event = platform_listen_device_needs_event(snd_device);
+ ALOGI("%s(): device 0x%x of type %d for Event %d, with Raise=%d",
+ __func__, snd_device, device_type, event, raise_event);
+ if (raise_event && (device_type == PCM_CAPTURE)) {
+ switch(event) {
+ case LISTEN_EVENT_SND_DEVICE_FREE:
+ listen_dev->notify_event(AUDIO_DEVICE_IN_INACTIVE);
+ break;
+ case LISTEN_EVENT_SND_DEVICE_BUSY:
+ listen_dev->notify_event(AUDIO_DEVICE_IN_ACTIVE);
+ break;
+ default:
+ ALOGW("%s:invalid event %d for device 0x%x",
+ __func__, event, snd_device);
+ }
+ }/*Events for output device, if required can be placed here in else*/
+ }
+}
- if (event == LISTEN_EVENT_SND_DEVICE_FREE)
- listen_dev->notify_event(AUDIO_CAPTURE_INACTIVE);
- else if (event == LISTEN_EVENT_SND_DEVICE_BUSY)
- listen_dev->notify_event(AUDIO_CAPTURE_ACTIVE);
+void audio_extn_listen_update_stream_status(struct audio_usecase *uc_info,
+ listen_event_type_t event)
+{
+ bool raise_event = false;
+ audio_usecase_t uc_id;
+ int usecase_type = -1;
+
+ if (uc_info == NULL) {
+ ALOGE("%s: usecase is NULL!!!", __func__);
+ return;
+ }
+ uc_id = uc_info->id;
+ usecase_type = uc_info->type;
+
+ if (listen_dev) {
+ raise_event = platform_listen_usecase_needs_event(uc_id);
+ ALOGI("%s(): uc_id %d of type %d for Event %d, with Raise=%d",
+ __func__, uc_id, usecase_type, event, raise_event);
+ if (raise_event && (usecase_type == PCM_PLAYBACK)) {
+ switch(event) {
+ case LISTEN_EVENT_STREAM_FREE:
+ listen_dev->notify_event(AUDIO_STREAM_OUT_INACTIVE);
+ break;
+ case LISTEN_EVENT_STREAM_BUSY:
+ listen_dev->notify_event(AUDIO_STREAM_OUT_ACTIVE);
+ break;
+ default:
+ ALOGW("%s:invalid event %d, for usecase %d",
+ __func__, event, uc_id);
+ }
+ }/*Events for capture usecase, if required can be placed here in else*/
}
}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 5793cce..37bbcba 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -257,6 +257,7 @@
audio_extn_dolby_set_dmid(adev);
audio_extn_dolby_set_endpoint(adev);
#endif
+ audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_BUSY);
audio_extn_utils_send_audio_calibration(adev, usecase);
audio_extn_utils_send_app_type_cfg(usecase);
strcpy(mixer_path, use_case_table[usecase->id]);
@@ -285,6 +286,7 @@
platform_add_backend_name(mixer_path, snd_device);
ALOGV("%s: reset and update mixer path: %s", __func__, mixer_path);
audio_route_reset_and_update_path(adev->audio_route, mixer_path);
+ audio_extn_listen_update_stream_status(usecase, LISTEN_EVENT_STREAM_FREE);
ALOGV("%s: exit", __func__);
return 0;
}
@@ -337,12 +339,12 @@
snd_device, device_name);
/* due to the possibility of calibration overwrite between listen
and audio, notify listen hal before audio calibration is sent */
- audio_extn_listen_update_status(snd_device,
- LISTEN_EVENT_SND_DEVICE_BUSY);
+ audio_extn_listen_update_device_status(snd_device,
+ LISTEN_EVENT_SND_DEVICE_BUSY);
if (platform_get_snd_device_acdb_id(snd_device) < 0) {
adev->snd_dev_ref_cnt[snd_device]--;
- audio_extn_listen_update_status(snd_device,
- LISTEN_EVENT_SND_DEVICE_FREE);
+ audio_extn_listen_update_device_status(snd_device,
+ LISTEN_EVENT_SND_DEVICE_FREE);
return -EINVAL;
}
audio_route_apply_and_update_path(adev->audio_route, device_name);
@@ -391,7 +393,7 @@
} else
audio_route_reset_and_update_path(adev->audio_route, device_name);
- audio_extn_listen_update_status(snd_device,
+ audio_extn_listen_update_device_status(snd_device,
LISTEN_EVENT_SND_DEVICE_FREE);
}
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index 81e7c43..ae136f1 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -1885,15 +1885,65 @@
return usecase;
}
-bool platform_listen_update_status(snd_device_t snd_device)
+bool platform_listen_device_needs_event(snd_device_t snd_device)
{
+ bool needs_event = false;
+
if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
(snd_device < SND_DEVICE_IN_END) &&
(snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
(snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
- return true;
- else
- return false;
+ needs_event = true;
+
+ return needs_event;
+}
+
+bool platform_listen_usecase_needs_event(audio_usecase_t uc_id)
+{
+ bool needs_event = false;
+
+ switch(uc_id){
+ /* concurrent playback usecases needs event */
+ case USECASE_AUDIO_PLAYBACK_DEEP_BUFFER:
+ case USECASE_AUDIO_PLAYBACK_MULTI_CH:
+ case USECASE_AUDIO_PLAYBACK_OFFLOAD:
+ needs_event = true;
+ break;
+ /* concurrent playback in low latency allowed */
+ case USECASE_AUDIO_PLAYBACK_LOW_LATENCY:
+ break;
+ /* concurrent playback FM needs event */
+ case USECASE_AUDIO_PLAYBACK_FM:
+ needs_event = true;
+ break;
+
+ /* concurrent capture usecases, no event, capture handled by device
+ * USECASE_AUDIO_RECORD:
+ * USECASE_AUDIO_RECORD_COMPRESS:
+ * USECASE_AUDIO_RECORD_LOW_LATENCY:
+
+ * USECASE_VOICE_CALL:
+ * USECASE_VOICE2_CALL:
+ * USECASE_VOLTE_CALL:
+ * USECASE_QCHAT_CALL:
+ * USECASE_VOWLAN_CALL:
+ * USECASE_COMPRESS_VOIP_CALL:
+ * USECASE_AUDIO_RECORD_FM_VIRTUAL:
+ * USECASE_INCALL_REC_UPLINK:
+ * USECASE_INCALL_REC_DOWNLINK:
+ * USECASE_INCALL_REC_UPLINK_AND_DOWNLINK:
+ * USECASE_INCALL_REC_UPLINK_COMPRESS:
+ * USECASE_INCALL_REC_DOWNLINK_COMPRESS:
+ * USECASE_INCALL_REC_UPLINK_AND_DOWNLINK_COMPRESS:
+ * USECASE_INCALL_MUSIC_UPLINK:
+ * USECASE_INCALL_MUSIC_UPLINK2:
+ * USECASE_AUDIO_SPKR_CALIB_RX:
+ * USECASE_AUDIO_SPKR_CALIB_TX:
+ */
+ default:
+ ALOGV("%s:usecase_id[%d} no need to raise event.", __func__, uc_id);
+ }
+ return needs_event;
}
/* Read offload buffer size from a property.
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index 70e0b9e..13f5473 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -914,7 +914,12 @@
return usecase;
}
-bool platform_listen_update_status(snd_device_t snd_device)
+bool platform_listen_device_needs_event(snd_device_t snd_device)
{
- return false;
+ return false;
+}
+
+bool platform_listen_usecase_needs_event(audio_usecase_t uc_id)
+{
+ return false;
}
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index ac747e4..364bbd2 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -1997,15 +1997,22 @@
return usecase;
}
-bool platform_listen_update_status(snd_device_t snd_device)
+bool platform_listen_device_needs_event(snd_device_t snd_device)
{
+ bool needs_event = false;
+
if ((snd_device >= SND_DEVICE_IN_BEGIN) &&
(snd_device < SND_DEVICE_IN_END) &&
(snd_device != SND_DEVICE_IN_CAPTURE_FM) &&
(snd_device != SND_DEVICE_IN_CAPTURE_VI_FEEDBACK))
- return true;
- else
- return false;
+ needs_event = true;
+
+ return needs_event;
+}
+
+bool platform_listen_usecase_needs_event(audio_usecase_t uc_id)
+{
+ return false;
}
/* Read offload buffer size from a property.
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 1e97adf..66b090e 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -67,7 +67,8 @@
int64_t platform_render_latency(audio_usecase_t usecase);
int platform_update_usecase_from_source(int source, audio_usecase_t usecase);
-bool platform_listen_update_status(snd_device_t snd_device);
+bool platform_listen_device_needs_event(snd_device_t snd_device);
+bool platform_listen_usecase_needs_event(audio_usecase_t uc_id);
/* From platform_info_parser.c */
int platform_info_init(const char *filename);