CRAS: iodev_list - Enable/disable active node for pinned stream
When a pinned stream is connected, the active node on the iodev-
to-pin might not work properly due to it was left in disabled
state when user's last action was switching to the other iodev.
Fix this problem by calling update_active_node() when a pinned
stream connected and removed.
BUG=chromium:700247
TEST=Plug 3.5mm headphone and a USB headset, select to headphone
in UI tray and then select to USB headset as output.
Execute 'cras_test_client --pin_device <id-of-internal-card>' to
play something, and verify audio coming out from headphone.
Next, click on UI to select to internal speaker and then select to
USB headset as output. Execute cras_test_client --pin_device to
play something, verify audio coming out from internal speaker this
time.
Change-Id: I438fdfc591b52186ed5a5079f8d3125b47f3499a
Reviewed-on: https://chromium-review.googlesource.com/462736
Commit-Ready: Hsinyu Chao <hychao@chromium.org>
Tested-by: Hsinyu Chao <hychao@chromium.org>
Reviewed-by: Chinyue Chen <chinyue@chromium.org>
diff --git a/cras/src/server/cras_iodev_list.c b/cras/src/server/cras_iodev_list.c
index 5eac3e6..b89767e 100644
--- a/cras/src/server/cras_iodev_list.c
+++ b/cras/src/server/cras_iodev_list.c
@@ -593,6 +593,28 @@
tm, INIT_DEV_DELAY_MS, init_device_cb, edev);
}
+static int pinned_stream_added(struct cras_rstream *rstream)
+{
+ struct cras_iodev *dev;
+ int rc;
+
+ /* Check that the target device is valid for pinned streams. */
+ dev = find_dev(rstream->pinned_dev_idx);
+ if (!dev)
+ return -EINVAL;
+
+ /* Make sure the active node is configured properly, it could be
+ * disabled when last normal stream removed. */
+ dev->update_active_node(dev, dev->active_node->idx, 1);
+
+ /* Negative EAGAIN code indicates dev will be opened later. */
+ rc = init_device(dev, rstream);
+ if (rc && (rc != -EAGAIN))
+ return rc;
+
+ return audio_thread_add_stream(audio_thread, rstream, &dev, 1);
+}
+
static int stream_added_cb(struct cras_rstream *rstream)
{
struct enabled_dev *edev;
@@ -603,20 +625,8 @@
if (stream_list_suspended)
return 0;
- /* Check that the target device is valid for pinned streams. */
- if (rstream->is_pinned) {
- struct cras_iodev *dev;
- dev = find_dev(rstream->pinned_dev_idx);
- if (!dev)
- return -EINVAL;
-
- /* Negative EAGAIN code indicates dev will be opened later. */
- rc = init_device(dev, rstream);
- if (rc && (rc != -EAGAIN))
- return rc;
-
- return audio_thread_add_stream(audio_thread, rstream, &dev, 1);
- }
+ if (rstream->is_pinned)
+ return pinned_stream_added(rstream);
/* Add the new stream to all enabled iodevs at once to avoid offset
* in shm level between different ouput iodevs. */
@@ -697,8 +707,10 @@
struct cras_iodev *dev;
dev = find_dev(rstream->pinned_dev_idx);
- if (!cras_iodev_list_dev_is_enabled(dev))
+ if (!cras_iodev_list_dev_is_enabled(dev)) {
close_dev(dev);
+ dev->update_active_node(dev, dev->active_node->idx, 0);
+ }
}
/* Returns the number of milliseconds left to drain this stream. This is passed