summaryrefslogtreecommitdiff
path: root/cras/src/server/cras_bt_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/server/cras_bt_io.c')
-rw-r--r--cras/src/server/cras_bt_io.c179
1 files changed, 31 insertions, 148 deletions
diff --git a/cras/src/server/cras_bt_io.c b/cras/src/server/cras_bt_io.c
index acdca809..637f0a79 100644
--- a/cras/src/server/cras_bt_io.c
+++ b/cras/src/server/cras_bt_io.c
@@ -8,7 +8,6 @@
#include "cras_bt_io.h"
#include "cras_bt_device.h"
-#include "cras_hfp_iodev.h"
#include "cras_utf8.h"
#include "cras_iodev.h"
#include "cras_iodev_list.h"
@@ -70,7 +69,7 @@ static struct cras_ionode *add_profile_dev(struct cras_iodev *bt_iodev,
n->base.type = CRAS_NODE_TYPE_BLUETOOTH;
n->base.volume = 100;
n->base.stable_id = dev->info.stable_id;
- n->base.capture_gain = 0;
+ n->base.max_software_gain = 0;
gettimeofday(&n->base.plugged_time, NULL);
strcpy(n->base.name, dev->info.name);
@@ -106,16 +105,6 @@ static void bt_switch_to_profile(struct cras_bt_device *device,
}
}
-/* Switches the active profile to A2DP if it can. */
-static void bt_possibly_switch_to_a2dp(struct bt_io *btio)
-{
- if (!cras_bt_device_has_a2dp(btio->device))
- return;
- cras_bt_device_set_active_profile(btio->device,
- CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
- cras_bt_device_switch_profile(btio->device, &btio->base);
-}
-
/* Checks if bt device is active for the given profile.
*/
static int device_using_profile(struct cras_bt_device *device,
@@ -136,7 +125,6 @@ static int open_dev(struct cras_iodev *iodev)
{
struct bt_io *btio = (struct bt_io *)iodev;
struct cras_iodev *dev = active_profile_dev(iodev);
- int rc;
/* Force to use HFP if opening input dev. */
if (device_using_profile(btio->device,
@@ -148,16 +136,8 @@ static int open_dev(struct cras_iodev *iodev)
return -EAGAIN;
}
- if (dev && dev->open_dev) {
- rc = dev->open_dev(dev);
- if (rc == 0)
- return 0;
-
- /* If input iodev open fails, switch profile back to A2DP. */
- if (iodev->direction == CRAS_STREAM_INPUT)
- bt_possibly_switch_to_a2dp(btio);
- return rc;
- }
+ if (dev && dev->open_dev)
+ return dev->open_dev(dev);
return 0;
}
@@ -170,6 +150,12 @@ static int update_supported_formats(struct cras_iodev *iodev)
if (!dev)
return -EINVAL;
+ if (dev->format == NULL) {
+ dev->format = (struct cras_audio_format *)malloc(
+ sizeof(*dev->format));
+ *dev->format = *iodev->format;
+ }
+
if (dev->update_supported_formats) {
rc = dev->update_supported_formats(dev);
if (rc)
@@ -200,9 +186,6 @@ static int update_supported_formats(struct cras_iodev *iodev)
(length + 1) * sizeof(*iodev->supported_formats));
for (i = 0; i < length + 1; i++)
iodev->supported_formats[i] = dev->supported_formats[i];
-
- /* Record max supported channels into cras_iodev_info. */
- iodev->info.max_supported_channels = dev->info.max_supported_channels;
return 0;
}
@@ -214,13 +197,7 @@ static int configure_dev(struct cras_iodev *iodev)
return -EINVAL;
/* Fill back the format iodev is using. */
- if (dev->format == NULL) {
- dev->format = (struct cras_audio_format *)malloc(
- sizeof(*dev->format));
- if (!dev->format)
- return -ENOMEM;
- *dev->format = *iodev->format;
- }
+ *dev->format = *iodev->format;
rc = dev->configure_dev(dev);
if (rc)
@@ -228,11 +205,6 @@ static int configure_dev(struct cras_iodev *iodev)
iodev->buffer_size = dev->buffer_size;
iodev->min_buffer_level = dev->min_buffer_level;
- if (dev->start)
- dev->state = CRAS_IODEV_STATE_OPEN;
- else
- dev->state = CRAS_IODEV_STATE_NO_STREAM_RUN;
-
return 0;
}
@@ -244,21 +216,22 @@ static int close_dev(struct cras_iodev *iodev)
if (!dev)
return -EINVAL;
- /* If input iodev is in open state and being closed, switch profile
- * from HFP to A2DP. */
- if (cras_iodev_is_open(iodev) &&
- device_using_profile(
+ /* Force back to A2DP if closing HFP. */
+ if (device_using_profile(
btio->device,
CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY |
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY) &&
- (iodev->direction == CRAS_STREAM_INPUT))
- bt_possibly_switch_to_a2dp(btio);
+ iodev->direction == CRAS_STREAM_INPUT &&
+ cras_bt_device_has_a2dp(btio->device)) {
+ cras_bt_device_set_active_profile(
+ btio->device, CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
+ cras_bt_device_switch_profile(btio->device, iodev);
+ }
rc = dev->close_dev(dev);
if (rc < 0)
return rc;
cras_iodev_free_format(iodev);
- dev->state = CRAS_IODEV_STATE_CLOSE;
return 0;
}
@@ -331,7 +304,6 @@ static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
struct cras_ionode *node;
struct bt_node *active = (struct bt_node *)iodev->active_node;
struct cras_iodev *dev;
- int rc;
if (device_using_profile(btio->device, active->profile))
goto leave;
@@ -355,38 +327,11 @@ leave:
dev = active_profile_dev(iodev);
if (dev && dev->update_active_node)
dev->update_active_node(dev, node_idx, dev_enabled);
-
- /* Update supported formats here to get the supported formats from the
- * new updated active profile dev.
- */
- rc = update_supported_formats(iodev);
- if (rc) {
- syslog(LOG_ERR, "Failed to update supported formats, rc=%d",
- rc);
- }
-}
-
-static int output_underrun(struct cras_iodev *iodev)
-{
- struct cras_iodev *dev = active_profile_dev(iodev);
- if (!dev)
- return -EINVAL;
-
- if (dev->output_underrun) {
- dev->min_cb_level = iodev->min_cb_level;
- dev->max_cb_level = iodev->max_cb_level;
- dev->buffer_size = iodev->buffer_size;
- return dev->output_underrun(dev);
- }
-
- return 0;
}
static int no_stream(struct cras_iodev *iodev, int enable)
{
struct cras_iodev *dev = active_profile_dev(iodev);
- int rc;
-
if (!dev)
return -EINVAL;
@@ -401,15 +346,8 @@ static int no_stream(struct cras_iodev *iodev, int enable)
dev->min_cb_level = iodev->min_cb_level;
dev->max_cb_level = iodev->max_cb_level;
dev->buffer_size = iodev->buffer_size;
- rc = dev->no_stream(dev, enable);
- if (rc < 0)
- return rc;
+ return dev->no_stream(dev, enable);
}
- if (enable)
- dev->state = CRAS_IODEV_STATE_NO_STREAM_RUN;
- else
- dev->state = CRAS_IODEV_STATE_NORMAL_RUN;
-
return 0;
}
@@ -428,45 +366,14 @@ static int is_free_running(const struct cras_iodev *iodev)
static int start(const struct cras_iodev *iodev)
{
struct cras_iodev *dev = active_profile_dev(iodev);
- int rc;
-
if (!dev)
return -EINVAL;
- if (dev->start) {
- rc = dev->start(dev);
- if (rc)
- return rc;
- }
- dev->state = CRAS_IODEV_STATE_NORMAL_RUN;
+ if (dev->start)
+ return dev->start(dev);
return 0;
}
-static unsigned int frames_to_play_in_sleep(struct cras_iodev *iodev,
- unsigned int *hw_level,
- struct timespec *hw_tstamp)
-{
- struct cras_iodev *dev = active_profile_dev(iodev);
- if (!dev || !dev->frames_to_play_in_sleep)
- return cras_iodev_default_frames_to_play_in_sleep(
- iodev, hw_level, hw_tstamp);
-
- return dev->frames_to_play_in_sleep(dev, hw_level, hw_tstamp);
-}
-
-static int get_valid_frames(struct cras_iodev *iodev,
- struct timespec *hw_tstamp)
-{
- struct cras_iodev *dev = active_profile_dev(iodev);
- if (!dev)
- return -EINVAL;
-
- if (dev->get_valid_frames)
- return dev->get_valid_frames(dev, hw_tstamp);
-
- return cras_iodev_frames_queued(iodev, hw_tstamp);
-}
-
struct cras_iodev *cras_bt_io_create(struct cras_bt_device *device,
struct cras_iodev *dev,
enum cras_bt_device_profile profile)
@@ -501,11 +408,8 @@ struct cras_iodev *cras_bt_io_create(struct cras_bt_device *device,
iodev->update_supported_formats = update_supported_formats;
iodev->update_active_node = update_active_node;
iodev->no_stream = no_stream;
- iodev->output_underrun = output_underrun;
iodev->is_free_running = is_free_running;
- iodev->get_valid_frames = get_valid_frames;
iodev->start = start;
- iodev->frames_to_play_in_sleep = frames_to_play_in_sleep;
/* Input also checks |software_volume_needed| flag for using software
* gain. Keep it as false for BT input.
@@ -518,30 +422,23 @@ struct cras_iodev *cras_bt_io_create(struct cras_bt_device *device,
iodev->set_volume = set_bt_volume;
}
- /* Create the fake node so it's the only node exposed to UI, and
- * point it to the first profile dev. */
+ /* Create the dummy node set to plugged so it's the only node exposed
+ * to UI, and point it to the first profile dev. */
active = (struct bt_node *)calloc(1, sizeof(*active));
if (!active)
- goto error;
+ return NULL;
active->base.dev = iodev;
active->base.idx = btio->next_node_id++;
- active->base.type = dev->active_node->type;
+ active->base.type = CRAS_NODE_TYPE_BLUETOOTH;
active->base.volume = 100;
- active->base.stable_id = cras_bt_device_get_stable_id(device);
- active->base.ui_gain_scaler = 1.0f;
- /*
- * If the same headset is connected in wideband mode, we shall assign
- * a separate stable_id so the node priority/preference mechanism in
- * Chrome UI doesn't break.
- */
- if ((active->base.type == CRAS_NODE_TYPE_BLUETOOTH) &&
- (dev->direction == CRAS_STREAM_INPUT))
- active->base.stable_id =
- SuperFastHash((const char *)&active->base.type,
- sizeof(active->base.type),
- active->base.stable_id);
+ active->base.plugged = 1;
+ active->base.stable_id =
+ SuperFastHash(cras_bt_device_object_path(device),
+ strlen(cras_bt_device_object_path(device)),
+ strlen(cras_bt_device_object_path(device)));
active->profile = profile;
active->profile_dev = dev;
+ gettimeofday(&active->base.plugged_time, NULL);
strcpy(active->base.name, dev->info.name);
/* The node name exposed to UI should be a valid UTF8 string. */
if (!is_utf8_string(active->base.name))
@@ -650,20 +547,6 @@ int cras_bt_io_on_profile(struct cras_iodev *bt_iodev,
return !!(profile & btnode->profile);
}
-enum cras_bt_device_profile
-cras_bt_io_profile_to_log(struct cras_iodev *bt_iodev)
-{
- struct bt_node *btnode = (struct bt_node *)bt_iodev->active_node;
-
- if (btnode->profile & CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE)
- return CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
-
- if (hfp_iodev_is_hsp(btnode->profile_dev))
- return CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
- else
- return CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY;
-}
-
unsigned int cras_bt_io_try_remove(struct cras_iodev *bt_iodev,
struct cras_iodev *dev)
{