diff options
Diffstat (limited to 'cras/src/server/cras_iodev_list.c')
-rw-r--r-- | cras/src/server/cras_iodev_list.c | 45 |
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; |