summaryrefslogtreecommitdiff
path: root/cras/src/server/cras_iodev_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/server/cras_iodev_list.c')
-rw-r--r--cras/src/server/cras_iodev_list.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/cras/src/server/cras_iodev_list.c b/cras/src/server/cras_iodev_list.c
index ada29719..b818c97b 100644
--- a/cras/src/server/cras_iodev_list.c
+++ b/cras/src/server/cras_iodev_list.c
@@ -91,6 +91,9 @@ static int stream_list_suspended = 0;
static const unsigned int INIT_DEV_DELAY_MS = 1000;
/* Flag to indicate that hotword streams are suspended. */
static int hotword_suspended = 0;
+/* Flag to indicate that suspended hotword streams should be auto-resumed at
+ * system resume. */
+static int hotword_auto_resume = 0;
static void idle_dev_check(struct cras_timer *timer, void *data);
@@ -388,8 +391,9 @@ static void close_dev(struct cras_iodev *dev)
MAINLOG(main_log, MAIN_THREAD_DEV_CLOSE, dev->info.idx, 0, 0);
remove_all_streams_from_dev(dev);
dev->idle_timeout.tv_sec = 0;
- cras_iodev_close(dev);
+ /* close echo ref first to avoid underrun in hardware */
possibly_disable_echo_reference(dev);
+ cras_iodev_close(dev);
}
static void idle_dev_check(struct cras_timer *timer, void *data)
@@ -490,6 +494,11 @@ static void suspend_devs()
if (rstream->is_pinned) {
struct cras_iodev *dev;
+ /* Skip closing hotword stream in the first pass.
+ * Closing an input device may resume hotword stream
+ * with its post_close_iodev_hook so we should deal
+ * with hotword stream in the second pass.
+ */
if ((rstream->flags & HOTWORD_STREAM) == HOTWORD_STREAM)
continue;
@@ -513,6 +522,14 @@ static void suspend_devs()
DL_FOREACH (enabled_devs[CRAS_STREAM_INPUT], edev) {
close_dev(edev->dev);
}
+
+ /* Doing this check after all the other enabled iodevs are closed to
+ * ensure preempted hotword streams obey the pause_at_suspend flag.
+ */
+ if (cras_system_get_hotword_pause_at_suspend()) {
+ cras_iodev_list_suspend_hotword_streams();
+ hotword_auto_resume = 1;
+ }
}
static int stream_added_cb(struct cras_rstream *rstream);
@@ -527,6 +544,14 @@ static void resume_devs()
MAINLOG(main_log, MAIN_THREAD_RESUME_DEVS, 0, 0, 0);
+ /* Auto-resume based on the local flag in case the system state flag has
+ * changed.
+ */
+ if (hotword_auto_resume) {
+ cras_iodev_list_resume_hotword_stream();
+ hotword_auto_resume = 0;
+ }
+
/*
* To remove the short popped noise caused by applications that can not
* stop playback "right away" after resume, we mute all output devices
@@ -1856,6 +1881,24 @@ void cras_iodev_list_unregister_loopback(enum CRAS_LOOPBACK_TYPE type,
}
}
+void cras_iodev_list_reset_for_noise_cancellation()
+{
+ struct cras_iodev *dev;
+ bool enabled = cras_system_get_noise_cancellation_enabled();
+
+ DL_FOREACH (devs[CRAS_STREAM_INPUT].iodevs, dev) {
+ if (!cras_iodev_is_open(dev) ||
+ !cras_iodev_support_noise_cancellation(dev))
+ continue;
+ syslog(LOG_INFO, "Re-open %s for %s noise cancellation",
+ dev->info.name, enabled ? "enabling" : "disabling");
+ possibly_enable_fallback(CRAS_STREAM_INPUT, false);
+ cras_iodev_list_suspend_dev(dev->info.idx);
+ cras_iodev_list_resume_dev(dev->info.idx);
+ possibly_disable_fallback(CRAS_STREAM_INPUT);
+ }
+}
+
void cras_iodev_list_reset()
{
struct enabled_dev *edev;