hal: Update keep_alive to support silence playback on non-hdmi devices
Keep_alive can now handle silence playback on multiple concurrent
devices such as primary output devices as well as HDMI
Change-Id: I08cbec51394d23255e1a61928e0b2cad552b2ac0
Signed-off-by: Md Mansoor Ahmed <mansoor@codeaurora.org>
diff --git a/hal/audio_extn/audio_defs.h b/hal/audio_extn/audio_defs.h
old mode 100644
new mode 100755
index 2a81ba1..3921f49
--- a/hal/audio_extn/audio_defs.h
+++ b/hal/audio_extn/audio_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 2017-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -190,6 +190,13 @@
int64_t adjust_time;
};
+/* Device playback mode passed to keep_alive_start & keep_alive_stop*/
+typedef enum {
+ KEEP_ALIVE_OUT_NONE = 0,
+ KEEP_ALIVE_OUT_PRIMARY,
+ KEEP_ALIVE_OUT_HDMI,
+} ka_mode_t;
+
/* type of asynchronous write callback events. Mutually exclusive
* event enums append those defined for stream_callback_event_t in audio.h */
typedef enum {
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
old mode 100644
new mode 100755
index b3ba566..e267e39
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -833,6 +833,7 @@
audio_extn_source_track_set_parameters(adev, parms);
audio_extn_fbsp_set_parameters(parms);
audio_extn_keep_alive_set_parameters(adev, parms);
+ audio_extn_passthru_set_parameters(adev, parms);
audio_extn_ext_disp_set_parameters(adev, parms);
audio_extn_qaf_set_parameters(adev, parms);
if (adev->offload_effects_set_parameters != NULL)
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
old mode 100644
new mode 100755
index 2239338..f29ca30
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
* Not a Contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -769,15 +769,17 @@
#endif
#ifndef KEEP_ALIVE_ENABLED
-#define audio_extn_keep_alive_init(a) do {} while(0)
-#define audio_extn_keep_alive_start() do {} while(0)
-#define audio_extn_keep_alive_stop() do {} while(0)
+#define audio_extn_keep_alive_init(adev) do {} while(0)
+#define audio_extn_keep_alive_deinit() do {} while(0)
+#define audio_extn_keep_alive_start(ka_mode) do {} while(0)
+#define audio_extn_keep_alive_stop(ka_mode) do {} while(0)
#define audio_extn_keep_alive_is_active() (false)
#define audio_extn_keep_alive_set_parameters(adev, parms) (0)
#else
void audio_extn_keep_alive_init(struct audio_device *adev);
-void audio_extn_keep_alive_start();
-void audio_extn_keep_alive_stop();
+void audio_extn_keep_alive_deinit();
+void audio_extn_keep_alive_start(ka_mode_t ka_mode);
+void audio_extn_keep_alive_stop(ka_mode_t ka_mode);
bool audio_extn_keep_alive_is_active();
int audio_extn_keep_alive_set_parameters(struct audio_device *adev,
struct str_parms *parms);
diff --git a/hal/audio_extn/keep_alive.c b/hal/audio_extn/keep_alive.c
old mode 100644
new mode 100755
index 698d8d0..0866a35
--- a/hal/audio_extn/keep_alive.c
+++ b/hal/audio_extn/keep_alive.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -55,6 +55,7 @@
typedef enum {
REQUEST_WRITE,
+ REQUEST_QUIT,
} request_t;
typedef struct {
@@ -66,8 +67,11 @@
state_t state;
struct listnode cmd_list;
struct pcm *pcm;
+ struct stream_out *out;
+ ka_mode_t prev_mode;
bool done;
void * userdata;
+ audio_devices_t active_devices;
} keep_alive_t;
struct keep_alive_cmd {
@@ -89,31 +93,8 @@
};
static void * keep_alive_loop(void * context);
-
-void audio_extn_keep_alive_init(struct audio_device *adev)
-{
- ka.userdata = adev;
- ka.state = STATE_IDLE;
- ka.pcm = NULL;
-
- if (property_get_bool("audio.keep_alive.disabled", false)) {
- ALOGE("keep alive disabled");
- ka.state = STATE_DISABLED;
- return;
- }
-
- pthread_mutex_init(&ka.lock, (const pthread_mutexattr_t *) NULL);
- pthread_cond_init(&ka.cond, (const pthread_condattr_t *) NULL);
- pthread_cond_init(&ka.wake_up_cond, (const pthread_condattr_t *) NULL);
- pthread_mutex_init(&ka.sleep_lock, (const pthread_mutexattr_t *) NULL);
- list_init(&ka.cmd_list);
- if (pthread_create(&ka.thread, (const pthread_attr_t *) NULL,
- keep_alive_loop, NULL) < 0) {
- ALOGW("Failed to create keep_alive_thread");
- /* can continue without keep alive */
- ka.state = STATE_DEINIT;
- }
-}
+static int keep_alive_cleanup();
+static int keep_alive_start_l();
static void send_cmd_l(request_t r)
{
@@ -133,277 +114,275 @@
pthread_cond_signal(&ka.cond);
}
-static int close_silence_stream()
+void audio_extn_keep_alive_init(struct audio_device *adev)
{
- if (!ka.pcm)
- return -ENODEV;
-
- pcm_close(ka.pcm);
+ ka.userdata = adev;
+ ka.state = STATE_IDLE;
ka.pcm = NULL;
- return 0;
+ if (property_get_bool("audio.keep_alive.disabled", false)) {
+ ALOGE("keep alive disabled");
+ ka.state = STATE_DISABLED;
+ return;
+ }
+ ka.done = false;
+ ka.prev_mode = KEEP_ALIVE_OUT_NONE;
+ ka.active_devices = AUDIO_DEVICE_NONE;
+ pthread_mutex_init(&ka.lock, (const pthread_mutexattr_t *) NULL);
+ pthread_cond_init(&ka.cond, (const pthread_condattr_t *) NULL);
+ pthread_cond_init(&ka.wake_up_cond, (const pthread_condattr_t *) NULL);
+ pthread_mutex_init(&ka.sleep_lock, (const pthread_mutexattr_t *) NULL);
+ list_init(&ka.cmd_list);
+ if (pthread_create(&ka.thread, (const pthread_attr_t *) NULL,
+ keep_alive_loop, NULL) < 0) {
+ ALOGW("Failed to create keep_alive_thread");
+ /* can continue without keep alive */
+ ka.state = STATE_DEINIT;
+ return;
+ }
+ ALOGV("%s init done", __func__);
}
-static int open_silence_stream()
+void audio_extn_keep_alive_deinit()
{
- unsigned int flags = PCM_OUT|PCM_MONOTONIC;
+ if (ka.state == STATE_DEINIT || ka.state == STATE_DISABLED)
+ return;
+ ka.userdata = NULL;
+ ka.done = true;
+ pthread_mutex_lock(&ka.lock);
+ send_cmd_l(REQUEST_QUIT);
+ pthread_mutex_unlock(&ka.lock);
+ pthread_join(ka.thread, (void **) NULL);
+ pthread_mutex_destroy(&ka.lock);
+ pthread_cond_destroy(&ka.cond);
+ pthread_cond_destroy(&ka.wake_up_cond);
+ pthread_mutex_destroy(&ka.sleep_lock);
+ ALOGV("%s deinit done", __func__);
+}
- if (ka.pcm)
- return -EEXIST;
-
- int silence_pcm_dev_id = platform_get_pcm_device_id(USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE,
- PCM_PLAYBACK);
-
- ALOGD("opening silence device %d", silence_pcm_dev_id);
+audio_devices_t get_device_id_from_mode(ka_mode_t ka_mode)
+{
struct audio_device * adev = (struct audio_device *)ka.userdata;
+ audio_devices_t out_device = AUDIO_DEVICE_NONE;
+ switch (ka_mode)
+ {
+ case KEEP_ALIVE_OUT_PRIMARY:
+ if (adev->primary_output) {
+ if (adev->primary_output->devices & AUDIO_DEVICE_OUT_ALL)
+ out_device = adev->primary_output->devices & AUDIO_DEVICE_OUT_ALL;
+ else
+ out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ }
+ else {
+ out_device = AUDIO_DEVICE_OUT_SPEAKER;
+ }
+ break;
+
+ case KEEP_ALIVE_OUT_HDMI:
+ out_device = AUDIO_DEVICE_OUT_AUX_DIGITAL;
+ break;
+
+ default:
+ out_device = AUDIO_DEVICE_NONE;
+ }
+ return out_device;
+}
+
+void audio_extn_keep_alive_start(ka_mode_t ka_mode)
+{
+ struct audio_device * adev = (struct audio_device *)ka.userdata;
+ audio_devices_t out_devices = AUDIO_DEVICE_NONE;
+
+ pthread_mutex_lock(&ka.lock);
+ ALOGV("%s: mode %x", __func__, ka_mode);
+ if ((ka.state == STATE_DISABLED)||(ka.state == STATE_DEINIT)) {
+ ALOGE(" %s : Unexpected state %x",__func__, ka.state);
+ goto exit;
+ }
+
+ out_devices = get_device_id_from_mode(ka_mode);
+ if ((out_devices == ka.active_devices) && (ka.state == STATE_ACTIVE)) {
+ ALOGV(" %s : Already feeding silence to device %x",__func__, out_devices);
+ ka.prev_mode |= ka_mode;
+ goto exit;
+ }
+ ALOGV(" %s : active devices %x, new device %x",__func__, ka.active_devices, out_devices);
+
+ if (out_devices == AUDIO_DEVICE_NONE)
+ goto exit;
+
+ if (audio_extn_passthru_is_active()) {
+ ka.active_devices &= ~AUDIO_DEVICE_OUT_AUX_DIGITAL;
+ if(ka.active_devices == AUDIO_DEVICE_NONE)
+ goto exit;
+ }
+
+ ka.active_devices |= out_devices;
+ ka.prev_mode |= ka_mode;
+ if (ka.state == STATE_ACTIVE) {
+ ka.out->devices = ka.active_devices;
+ select_devices(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
+ } else if (ka.state == STATE_IDLE) {
+ keep_alive_start_l();
+ }
+
+exit:
+ pthread_mutex_unlock(&ka.lock);
+}
+
+/* must be called with adev lock held */
+static int keep_alive_start_l()
+{
+ struct audio_device * adev = (struct audio_device *)ka.userdata;
+ unsigned int flags = PCM_OUT|PCM_MONOTONIC;
+ struct audio_usecase *usecase;
+ int rc = 0;
+
+ int silence_pcm_dev_id =
+ platform_get_pcm_device_id(USECASE_AUDIO_PLAYBACK_SILENCE,
+ PCM_PLAYBACK);
+
+ ka.done = false;
+ usecase = calloc(1, sizeof(struct audio_usecase));
+ if (usecase == NULL) {
+ ALOGE("%s: usecase is NULL", __func__);
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ ka.out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
+ if (ka.out == NULL) {
+ ALOGE("%s: keep_alive out is NULL", __func__);
+ free(usecase);
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ ka.out->flags = 0;
+ ka.out->devices = ka.active_devices;
+ ka.out->dev = adev;
+ ka.out->format = AUDIO_FORMAT_PCM_16_BIT;
+ ka.out->sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+ ka.out->channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ ka.out->supported_channel_masks[0] = AUDIO_CHANNEL_OUT_STEREO;
+ ka.out->config = silence_config;
+
+ usecase->stream.out = ka.out;
+ usecase->type = PCM_PLAYBACK;
+ usecase->id = USECASE_AUDIO_PLAYBACK_SILENCE;
+ usecase->out_snd_device = SND_DEVICE_NONE;
+ usecase->in_snd_device = SND_DEVICE_NONE;
+
+ list_add_tail(&adev->usecase_list, &usecase->list);
+ select_devices(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
+
+ ALOGD("opening pcm device for silence playback %x", silence_pcm_dev_id);
ka.pcm = pcm_open(adev->snd_card, silence_pcm_dev_id,
flags, &silence_config);
- ALOGD("opened silence device %d", silence_pcm_dev_id);
if (ka.pcm == NULL || !pcm_is_ready(ka.pcm)) {
ALOGE("%s: %s", __func__, pcm_get_error(ka.pcm));
if (ka.pcm != NULL) {
pcm_close(ka.pcm);
ka.pcm = NULL;
}
- return -1;
+ goto exit;
}
- return 0;
+ send_cmd_l(REQUEST_WRITE);
+ while (ka.state != STATE_ACTIVE) {
+ pthread_cond_wait(&ka.cond, &ka.lock);
+ }
+ return rc;
+exit:
+ keep_alive_cleanup();
+ return rc;
}
-
-static int set_mixer_control(struct mixer *mixer,
- const char * mixer_ctl_name,
- const char *mixer_val)
-{
- struct mixer_ctl *ctl;
- if ((mixer == NULL) || (mixer_ctl_name == NULL) || (mixer_val == NULL)) {
- ALOGE("%s: Invalid input", __func__);
- return -EINVAL;
- }
- ALOGD("setting mixer ctl %s with value %s", mixer_ctl_name, mixer_val);
- ctl = mixer_get_ctl_by_name(mixer, mixer_ctl_name);
- if (!ctl) {
- ALOGE("%s: could not get ctl for mixer cmd - %s",
- __func__, mixer_ctl_name);
- return -EINVAL;
- }
-
- return mixer_ctl_set_enum_by_string(ctl, mixer_val);
-}
-
-/* must be called with adev lock held */
-void audio_extn_keep_alive_start()
+void audio_extn_keep_alive_stop(ka_mode_t ka_mode)
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
- char mixer_ctl_name[MAX_LENGTH_MIXER_CONTROL_IN_INT];
- long app_type_cfg[MAX_LENGTH_MIXER_CONTROL_IN_INT];
- int len = 0, rc;
- struct mixer_ctl *ctl;
- int acdb_dev_id, snd_device;
- struct listnode *node;
- struct audio_usecase *usecase;
- int32_t sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
-
+ audio_devices_t out_devices;
if (ka.state == STATE_DISABLED)
return;
pthread_mutex_lock(&ka.lock);
- if (ka.state == STATE_DEINIT) {
- ALOGE(" %s : Invalid state ",__func__);
+ ALOGV("%s: mode %x", __func__, ka_mode);
+ if (ka_mode && (ka.state != STATE_ACTIVE)) {
+ ALOGV(" %s : Can't stop, keep_alive",__func__);
+ ALOGV(" %s : keep_alive is not running on device %x",__func__, get_device_id_from_mode(ka_mode));
+ ka.prev_mode |= ka_mode;
goto exit;
}
-
- if (audio_extn_passthru_is_active()) {
- ALOGE(" %s : Pass through is already active", __func__);
- goto exit;
+ out_devices = get_device_id_from_mode(ka_mode);
+ if (ka.prev_mode & ka_mode) {
+ ka.prev_mode &= ~ka_mode;
+ ka.active_devices = get_device_id_from_mode(ka.prev_mode);
}
- if (ka.state == STATE_ACTIVE) {
- ALOGV(" %s : Keep alive state is already Active",__func__ );
- goto exit;
+ if (ka.active_devices == AUDIO_DEVICE_NONE) {
+ keep_alive_cleanup();
+ } else if (ka.out->devices != ka.active_devices){
+ ka.out->devices = ka.active_devices;
+ select_devices(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
}
-
- /* Dont start keep_alive if any other PCM session is routed to HDMI*/
- list_for_each(node, &adev->usecase_list) {
- usecase = node_to_item(node, struct audio_usecase, list);
- if (usecase->type == PCM_PLAYBACK &&
- usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
- goto exit;
- }
-
- ka.done = false;
-
- /*configure app type */
- int silence_pcm_dev_id = platform_get_pcm_device_id(USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE,
- PCM_PLAYBACK);
- snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
- "Audio Stream %d App Type Cfg", silence_pcm_dev_id);
-
- 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);
- rc = -EINVAL;
- goto exit;
- }
-
- /* Configure HDMI/DP Backend with default values, this as well
- * helps reconfigure HDMI/DP backend after passthrough.
- */
- int ext_disp_type = platform_get_ext_disp_type(adev->platform);
- switch(ext_disp_type) {
- case EXT_DISPLAY_TYPE_HDMI:
- snd_device = SND_DEVICE_OUT_HDMI;
- set_mixer_control(adev->mixer, "HDMI RX Format", "LPCM");
- set_mixer_control(adev->mixer, "HDMI_RX SampleRate", "KHZ_48");
- set_mixer_control(adev->mixer, "HDMI_RX Channels", "Two");
- break;
- case EXT_DISPLAY_TYPE_DP:
- snd_device = SND_DEVICE_OUT_DISPLAY_PORT;
- set_mixer_control(adev->mixer, "Display Port RX Format", "LPCM");
- set_mixer_control(adev->mixer, "Display Port RX SampleRate", "KHZ_48");
- set_mixer_control(adev->mixer, "Display Port RX Channels", "Two");
- break;
- default:
- ALOGE("%s: Invalid external display type:%d", __func__, ext_disp_type);
- goto exit;
- }
-
- acdb_dev_id = platform_get_snd_device_acdb_id(snd_device);
- if (acdb_dev_id < 0) {
- ALOGE("%s: Couldn't get the acdb dev id", __func__);
- rc = -EINVAL;
- goto exit;
- }
-
- sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
- app_type_cfg[len++] = platform_get_default_app_type(adev->platform);
- app_type_cfg[len++] = acdb_dev_id;
- app_type_cfg[len++] = sample_rate;
-
- ALOGI("%s:%d PLAYBACK app_type %d, acdb_dev_id %d, sample_rate %d",
- __func__, __LINE__,
- platform_get_default_app_type(adev->platform),
- acdb_dev_id, sample_rate);
- mixer_ctl_set_array(ctl, app_type_cfg, len);
-
- /*send calibration*/
- usecase = calloc(1, sizeof(struct audio_usecase));
-
- if (usecase == NULL) {
- ALOGE("%s: usecase is NULL", __func__);
- rc = -ENOMEM;
- goto exit;
- }
- usecase->type = PCM_PLAYBACK;
- usecase->out_snd_device = snd_device;
-
- platform_send_audio_calibration(adev->platform, usecase,
- platform_get_default_app_type(adev->platform), sample_rate);
-
- /*apply audio route */
- switch(ext_disp_type) {
- case EXT_DISPLAY_TYPE_HDMI:
- audio_route_apply_and_update_path(adev->audio_route, "silence-playback hdmi");
- break;
- case EXT_DISPLAY_TYPE_DP:
- audio_route_apply_and_update_path(adev->audio_route, "silence-playback display-port");
- break;
- default:
- ALOGE("%s: Invalid external display type:%d", __func__, ext_disp_type);
- goto exit;
- }
-
- if (open_silence_stream() == 0) {
- send_cmd_l(REQUEST_WRITE);
- while (ka.state != STATE_ACTIVE) {
- pthread_cond_wait(&ka.cond, &ka.lock);
- }
- }
-
exit:
pthread_mutex_unlock(&ka.lock);
}
/* must be called with adev lock held */
-void audio_extn_keep_alive_stop()
+static int keep_alive_cleanup()
{
struct audio_device * adev = (struct audio_device *)ka.userdata;
+ struct audio_usecase *uc_info;
- if (ka.state == STATE_DISABLED)
- return;
-
- pthread_mutex_lock(&ka.lock);
-
- if ((ka.state == STATE_DEINIT) || (ka.state == STATE_IDLE))
- goto exit;
+ ka.done = true;
+ if (ka.out != NULL)
+ free(ka.out);
pthread_mutex_lock(&ka.sleep_lock);
- ka.done = true;
pthread_cond_signal(&ka.wake_up_cond);
pthread_mutex_unlock(&ka.sleep_lock);
while (ka.state != STATE_IDLE) {
pthread_cond_wait(&ka.cond, &ka.lock);
}
- close_silence_stream();
+ ALOGV("%s: keep_alive state changed to %x", __func__, ka.state);
- /*apply audio route */
- int ext_disp_type = platform_get_ext_disp_type(adev->platform);
- switch(ext_disp_type) {
- case EXT_DISPLAY_TYPE_HDMI:
- audio_route_reset_and_update_path(adev->audio_route, "silence-playback hdmi");
- break;
- case EXT_DISPLAY_TYPE_DP:
- audio_route_reset_and_update_path(adev->audio_route, "silence-playback display-port");
- break;
- default:
- ALOGE("%s: Invalid external display type:%d", __func__, ext_disp_type);
+ uc_info = get_usecase_from_list(adev, USECASE_AUDIO_PLAYBACK_SILENCE);
+ if (uc_info == NULL) {
+ ALOGE("%s: Could not find keep alive usecase in the list", __func__);
+ } else {
+ disable_audio_route(adev, uc_info);
+ disable_snd_device(adev, uc_info->out_snd_device);
+ list_remove(&uc_info->list);
+ free(uc_info);
}
-
-exit:
- pthread_mutex_unlock(&ka.lock);
-}
-
-bool audio_extn_keep_alive_is_active()
-{
- return ka.state == STATE_ACTIVE;
+ pcm_close(ka.pcm);
+ ka.pcm = NULL;
+ ka.active_devices = KEEP_ALIVE_OUT_NONE;
+ return 0;
}
int audio_extn_keep_alive_set_parameters(struct audio_device *adev __unused,
- struct str_parms *parms)
+ struct str_parms *parms __unused)
{
char value[32];
- int ret;
-
+ int ret, pcm_device_id=0;
if (ka.state == STATE_DISABLED)
return 0;
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value, sizeof(value));
- if (ret >= 0) {
- int val = atoi(value);
- if (audio_is_output_devices(val) &&
- (val & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
- if (!audio_extn_passthru_is_active()) {
- ALOGV("start keep alive");
- audio_extn_keep_alive_start();
+ if ((ka.state == STATE_ACTIVE) && (ka.prev_mode & KEEP_ALIVE_OUT_PRIMARY)){
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING,
+ value, sizeof(value));
+ if (ret >= 0) {
+ pcm_device_id = atoi(value);
+ if(pcm_device_id > 0)
+ {
+ audio_extn_keep_alive_start(KEEP_ALIVE_OUT_PRIMARY);
}
}
}
-
- ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
- sizeof(value));
- if (ret >= 0) {
- int val = atoi(value);
- if (audio_is_output_devices(val) &&
- (val & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
- ALOGV("stop keep_alive");
- audio_extn_keep_alive_stop();
- }
- }
return 0;
}
-
static void * keep_alive_loop(void * context __unused)
{
struct keep_alive_cmd *cmd = NULL;
@@ -424,7 +403,11 @@
cmd = node_to_item(item, struct keep_alive_cmd, node);
list_remove(item);
- if (cmd->req != REQUEST_WRITE) {
+ if (cmd->req == REQUEST_QUIT) {
+ free(cmd);
+ pthread_mutex_unlock(&ka.lock);
+ break;
+ } else if (cmd->req != REQUEST_WRITE) {
free(cmd);
pthread_mutex_unlock(&ka.lock);
continue;
@@ -432,6 +415,7 @@
free(cmd);
ka.state = STATE_ACTIVE;
+ ALOGV("%s: state changed to %x", __func__, ka.state);
pthread_cond_signal(&ka.cond);
pthread_mutex_unlock(&ka.lock);
@@ -462,6 +446,7 @@
}
pthread_mutex_lock(&ka.lock);
ka.state = STATE_IDLE;
+ ALOGV("%s: state changed to %x", __func__, ka.state);
pthread_cond_signal(&ka.cond);
pthread_mutex_unlock(&ka.lock);
}
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
old mode 100644
new mode 100755
index f8974c7..99949fc
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -309,8 +309,8 @@
}
if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- ALOGI("passthru on aux digital, start keep alive");
- audio_extn_keep_alive_start();
+ ALOGD("%s: passthru on aux digital, start keep alive", __func__);
+ audio_extn_keep_alive_start(KEEP_ALIVE_OUT_HDMI);
}
}
@@ -321,8 +321,30 @@
}
int audio_extn_passthru_set_parameters(struct audio_device *adev __unused,
- struct str_parms *parms __unused)
+ struct str_parms *parms)
{
+ char value[32];
+ int ret;
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_CONNECT, value, sizeof(value));
+ if (ret >= 0) {
+ int val = atoi(value);
+ if (val & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ if (!audio_extn_passthru_is_active()) {
+ ALOGV("%s: start keep alive on aux digital", __func__);
+ audio_extn_keep_alive_start(KEEP_ALIVE_OUT_HDMI);
+ }
+ }
+ }
+
+ ret = str_parms_get_str(parms, AUDIO_PARAMETER_DEVICE_DISCONNECT, value,
+ sizeof(value));
+ if (ret >= 0) {
+ int val = atoi(value);
+ if (val & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+ ALOGV("%s: stop keep_alive on aux digital on device", __func__);
+ audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_HDMI);
+ }
+ }
return 0;
}
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
old mode 100644
new mode 100755
index 0444766..1a8f0a1
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -334,7 +334,7 @@
[USECASE_AUDIO_PLAYBACK_AFE_PROXY] = "afe-proxy-playback",
[USECASE_AUDIO_RECORD_AFE_PROXY] = "afe-proxy-record",
- [USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE] = "silence-playback",
+ [USECASE_AUDIO_PLAYBACK_SILENCE] = "silence-playback",
/* Transcode loopback cases */
[USECASE_AUDIO_TRANSCODE_LOOPBACK] = "audio-transcode-loopback",
@@ -2879,7 +2879,7 @@
/* Must be called after removing the usecase from list */
if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)
- audio_extn_keep_alive_start();
+ audio_extn_keep_alive_start(KEEP_ALIVE_OUT_HDMI);
if (out->ip_hdlr_handle) {
ret = audio_extn_ip_hdlr_intf_close(out->ip_hdlr_handle, true, out);
@@ -2973,7 +2973,7 @@
adev->perf_lock_opts_size);
if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
- audio_extn_keep_alive_stop();
+ audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_HDMI);
if (audio_extn_passthru_is_enabled() &&
audio_extn_passthru_is_passthrough_stream(out)) {
audio_extn_passthru_on_start(out);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
old mode 100644
new mode 100755
index 7d1888f..0dc9115
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
* Not a contribution.
*
* Copyright (C) 2013 The Android Open Source Project
@@ -187,7 +187,7 @@
USECASE_AUDIO_PLAYBACK_AFE_PROXY,
USECASE_AUDIO_RECORD_AFE_PROXY,
- USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE,
+ USECASE_AUDIO_PLAYBACK_SILENCE,
USECASE_AUDIO_TRANSCODE_LOOPBACK,
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
old mode 100644
new mode 100755
index 2ee54ee..930c5d4
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -385,7 +385,7 @@
AFE_PROXY_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
AFE_PROXY_RECORD_PCM_DEVICE},
- [USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
+ [USECASE_AUDIO_PLAYBACK_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
[USECASE_AUDIO_TRANSCODE_LOOPBACK] = {TRANSCODE_LOOPBACK_RX_DEV_ID, TRANSCODE_LOOPBACK_TX_DEV_ID},
[USECASE_AUDIO_PLAYBACK_VOIP] = {AUDIO_PLAYBACK_VOIP_PCM_DEVICE, AUDIO_PLAYBACK_VOIP_PCM_DEVICE},
[USECASE_AUDIO_RECORD_VOIP] = {AUDIO_RECORD_VOIP_PCM_DEVICE, AUDIO_RECORD_VOIP_PCM_DEVICE},
@@ -910,7 +910,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO)},
{TO_NAME_INDEX(USECASE_AUDIO_HFP_SCO_WB)},
{TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
- {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE)},
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_SILENCE)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_FM)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_FM_VIRTUAL)},
{TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_RX)},
@@ -2661,6 +2661,9 @@
}
}
+ /* Initialize keep alive for HDMI/loopback silence */
+ audio_extn_keep_alive_init(adev);
+
ret = audio_extn_utils_get_codec_version(snd_card_name,
my_data->adev->snd_card,
my_data->codec_version);
@@ -2696,6 +2699,8 @@
{
struct platform_data *my_data = (struct platform_data *)platform;
+ audio_extn_keep_alive_deinit();
+
if (my_data->edid_info) {
free(my_data->edid_info);
my_data->edid_info = NULL;
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
old mode 100644
new mode 100755
index b708a48..da2ccb6
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -367,7 +367,7 @@
AFE_PROXY_RECORD_PCM_DEVICE},
[USECASE_AUDIO_RECORD_AFE_PROXY] = {AFE_PROXY_PLAYBACK_PCM_DEVICE,
AFE_PROXY_RECORD_PCM_DEVICE},
- [USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
+ [USECASE_AUDIO_PLAYBACK_SILENCE] = {MULTIMEDIA9_PCM_DEVICE, -1},
[USECASE_AUDIO_TRANSCODE_LOOPBACK] = {TRANSCODE_LOOPBACK_RX_DEV_ID, TRANSCODE_LOOPBACK_TX_DEV_ID},
[USECASE_AUDIO_PLAYBACK_VOIP] = {AUDIO_PLAYBACK_VOIP_PCM_DEVICE, AUDIO_PLAYBACK_VOIP_PCM_DEVICE},
@@ -894,7 +894,7 @@
{TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_TX)},
{TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_AFE_PROXY)},
{TO_NAME_INDEX(USECASE_AUDIO_RECORD_AFE_PROXY)},
- {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_EXT_DISP_SILENCE)},
+ {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_SILENCE)},
};
#define NO_COLS 2
@@ -2496,6 +2496,9 @@
if (property_get_bool("vendor.audio.apptype.multirec.enabled", false))
my_data->use_generic_handset = true;
+ /* Initialize keep alive for HDMI/loopback silence */
+ audio_extn_keep_alive_init(adev);
+
my_data->edid_info = NULL;
free(snd_card_name);
free(snd_card_name_t);
@@ -2506,6 +2509,8 @@
{
struct platform_data *my_data = (struct platform_data *)platform;
+ audio_extn_keep_alive_deinit();
+
if (my_data->edid_info) {
free(my_data->edid_info);
my_data->edid_info = NULL;