summaryrefslogtreecommitdiff
path: root/cras/src/server/cras_observer.c
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/server/cras_observer.c')
-rw-r--r--cras/src/server/cras_observer.c634
1 files changed, 0 insertions, 634 deletions
diff --git a/cras/src/server/cras_observer.c b/cras/src/server/cras_observer.c
deleted file mode 100644
index 0f17dc92..00000000
--- a/cras/src/server/cras_observer.c
+++ /dev/null
@@ -1,634 +0,0 @@
-/* Copyright 2016 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "cras_observer.h"
-
-#include "cras_alert.h"
-#include "cras_iodev_list.h"
-#include "cras_types.h"
-#include "utlist.h"
-
-struct cras_observer_client {
- struct cras_observer_ops ops;
- void *context;
- struct cras_observer_client *next, *prev;
-};
-
-struct cras_observer_alerts {
- struct cras_alert *output_volume;
- struct cras_alert *output_mute;
- struct cras_alert *capture_gain;
- struct cras_alert *capture_mute;
- struct cras_alert *nodes;
- struct cras_alert *active_node;
- struct cras_alert *output_node_volume;
- struct cras_alert *node_left_right_swapped;
- struct cras_alert *input_node_gain;
- struct cras_alert *suspend_changed;
- struct cras_alert *hotword_triggered;
- /* If all events for active streams went through a single alert then
- * we might miss some because the alert code does not send every
- * alert message. To ensure that the event sent contains the correct
- * number of active streams per direction, make the alerts
- * per-direciton. */
- struct cras_alert *num_active_streams[CRAS_NUM_DIRECTIONS];
- struct cras_alert *non_empty_audio_state_changed;
- struct cras_alert *bt_battery_changed;
- struct cras_alert *num_input_streams_with_permission;
-};
-
-struct cras_observer_server {
- struct cras_observer_alerts alerts;
- struct cras_observer_client *clients;
-};
-
-struct cras_observer_alert_data_volume {
- int32_t volume;
-};
-
-struct cras_observer_alert_data_mute {
- int muted;
- int user_muted;
- int mute_locked;
-};
-
-struct cras_observer_alert_data_active_node {
- enum CRAS_STREAM_DIRECTION direction;
- cras_node_id_t node_id;
-};
-
-struct cras_observer_alert_data_node_volume {
- cras_node_id_t node_id;
- int32_t volume;
-};
-
-struct cras_observer_alert_data_node_lr_swapped {
- cras_node_id_t node_id;
- int swapped;
-};
-
-struct cras_observer_alert_data_suspend {
- int suspended;
-};
-
-struct cras_observer_alert_data_streams {
- enum CRAS_STREAM_DIRECTION direction;
- uint32_t num_active_streams;
-};
-
-struct cras_observer_alert_data_input_streams {
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE];
-};
-
-struct cras_observer_alert_data_hotword_triggered {
- int64_t tv_sec;
- int64_t tv_nsec;
-};
-
-struct cras_observer_non_empty_audio_state {
- int non_empty;
-};
-
-struct cras_observer_alert_data_bt_battery_changed {
- const char *address;
- uint32_t level;
-};
-
-/* Global observer instance. */
-static struct cras_observer_server *g_observer;
-
-/* Empty observer ops. */
-static struct cras_observer_ops g_empty_ops;
-
-/*
- * Alert handlers for delayed callbacks.
- */
-
-static void output_volume_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_volume *volume_data =
- (struct cras_observer_alert_data_volume *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.output_volume_changed)
- client->ops.output_volume_changed(client->context,
- volume_data->volume);
- }
-}
-
-static void output_mute_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_mute *mute_data =
- (struct cras_observer_alert_data_mute *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.output_mute_changed)
- client->ops.output_mute_changed(client->context,
- mute_data->muted,
- mute_data->user_muted,
- mute_data->mute_locked);
- }
-}
-
-static void capture_gain_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_volume *volume_data =
- (struct cras_observer_alert_data_volume *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.capture_gain_changed)
- client->ops.capture_gain_changed(client->context,
- volume_data->volume);
- }
-}
-
-static void capture_mute_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_mute *mute_data =
- (struct cras_observer_alert_data_mute *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.capture_mute_changed)
- client->ops.capture_mute_changed(
- client->context, mute_data->muted,
- mute_data->mute_locked);
- }
-}
-
-static void nodes_prepare(struct cras_alert *alert)
-{
- cras_iodev_list_update_device_list();
-}
-
-static void nodes_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.nodes_changed)
- client->ops.nodes_changed(client->context);
- }
-}
-
-static void active_node_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_active_node *node_data =
- (struct cras_observer_alert_data_active_node *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.active_node_changed)
- client->ops.active_node_changed(client->context,
- node_data->direction,
- node_data->node_id);
- }
-}
-
-static void output_node_volume_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_node_volume *node_data =
- (struct cras_observer_alert_data_node_volume *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.output_node_volume_changed)
- client->ops.output_node_volume_changed(
- client->context, node_data->node_id,
- node_data->volume);
- }
-}
-
-static void node_left_right_swapped_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_node_lr_swapped *node_data =
- (struct cras_observer_alert_data_node_lr_swapped *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.node_left_right_swapped_changed)
- client->ops.node_left_right_swapped_changed(
- client->context, node_data->node_id,
- node_data->swapped);
- }
-}
-
-static void input_node_gain_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_node_volume *node_data =
- (struct cras_observer_alert_data_node_volume *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.input_node_gain_changed)
- client->ops.input_node_gain_changed(client->context,
- node_data->node_id,
- node_data->volume);
- }
-}
-
-static void suspend_changed_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_suspend *suspend_data =
- (struct cras_observer_alert_data_suspend *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.suspend_changed)
- client->ops.suspend_changed(client->context,
- suspend_data->suspended);
- }
-}
-
-static void num_active_streams_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_streams *streams_data =
- (struct cras_observer_alert_data_streams *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.num_active_streams_changed)
- client->ops.num_active_streams_changed(
- client->context, streams_data->direction,
- streams_data->num_active_streams);
- }
-}
-
-static void num_input_streams_with_permission_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_input_streams *input_streams_data =
- (struct cras_observer_alert_data_input_streams *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.num_input_streams_with_permission_changed)
- client->ops.num_input_streams_with_permission_changed(
- client->context,
- input_streams_data->num_input_streams);
- }
-}
-
-static void hotword_triggered_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_hotword_triggered *triggered_data =
- (struct cras_observer_alert_data_hotword_triggered *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.hotword_triggered)
- client->ops.hotword_triggered(client->context,
- triggered_data->tv_sec,
- triggered_data->tv_nsec);
- }
-}
-
-static void non_empty_audio_state_changed_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_non_empty_audio_state *non_empty_audio_data =
- (struct cras_observer_non_empty_audio_state *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.non_empty_audio_state_changed) {
- client->ops.non_empty_audio_state_changed(
- client->context,
- non_empty_audio_data->non_empty);
- }
- }
-}
-
-static void bt_battery_changed_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_bt_battery_changed *triggered_data =
- (struct cras_observer_alert_data_bt_battery_changed *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.bt_battery_changed)
- client->ops.bt_battery_changed(client->context,
- triggered_data->address,
- triggered_data->level);
- }
-}
-
-static int cras_observer_server_set_alert(struct cras_alert **alert,
- cras_alert_cb cb,
- cras_alert_prepare prepare,
- unsigned int flags)
-{
- *alert = cras_alert_create(prepare, flags);
- if (!*alert)
- return -ENOMEM;
- return cras_alert_add_callback(*alert, cb, NULL);
-}
-
-#define CRAS_OBSERVER_SET_ALERT(alert, prepare, flags) \
- do { \
- rc = cras_observer_server_set_alert(&g_observer->alerts.alert, \
- alert##_alert, prepare, \
- flags); \
- if (rc) \
- goto error; \
- } while (0)
-
-#define CRAS_OBSERVER_SET_ALERT_WITH_DIRECTION(alert, direction) \
- do { \
- rc = cras_observer_server_set_alert( \
- &g_observer->alerts.alert[direction], alert##_alert, \
- NULL, 0); \
- if (rc) \
- goto error; \
- } while (0)
-
-/*
- * Public interface
- */
-
-int cras_observer_server_init()
-{
- int rc;
-
- memset(&g_empty_ops, 0, sizeof(g_empty_ops));
- g_observer = (struct cras_observer_server *)calloc(
- 1, sizeof(struct cras_observer_server));
- if (!g_observer)
- return -ENOMEM;
-
- CRAS_OBSERVER_SET_ALERT(output_volume, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(output_mute, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(capture_gain, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(capture_mute, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(nodes, nodes_prepare, 0);
- CRAS_OBSERVER_SET_ALERT(active_node, nodes_prepare,
- CRAS_ALERT_FLAG_KEEP_ALL_DATA);
- CRAS_OBSERVER_SET_ALERT(output_node_volume, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(node_left_right_swapped, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(input_node_gain, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(suspend_changed, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(hotword_triggered, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(non_empty_audio_state_changed, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(bt_battery_changed, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(num_input_streams_with_permission, NULL, 0);
-
- CRAS_OBSERVER_SET_ALERT_WITH_DIRECTION(num_active_streams,
- CRAS_STREAM_OUTPUT);
- CRAS_OBSERVER_SET_ALERT_WITH_DIRECTION(num_active_streams,
- CRAS_STREAM_INPUT);
- CRAS_OBSERVER_SET_ALERT_WITH_DIRECTION(num_active_streams,
- CRAS_STREAM_POST_MIX_PRE_DSP);
-
- return 0;
-
-error:
- cras_observer_server_free();
- return rc;
-}
-
-void cras_observer_server_free()
-{
- if (!g_observer)
- return;
- cras_alert_destroy(g_observer->alerts.output_volume);
- cras_alert_destroy(g_observer->alerts.output_mute);
- cras_alert_destroy(g_observer->alerts.capture_gain);
- cras_alert_destroy(g_observer->alerts.capture_mute);
- cras_alert_destroy(g_observer->alerts.nodes);
- cras_alert_destroy(g_observer->alerts.active_node);
- cras_alert_destroy(g_observer->alerts.output_node_volume);
- cras_alert_destroy(g_observer->alerts.node_left_right_swapped);
- cras_alert_destroy(g_observer->alerts.input_node_gain);
- cras_alert_destroy(g_observer->alerts.suspend_changed);
- cras_alert_destroy(g_observer->alerts.hotword_triggered);
- cras_alert_destroy(g_observer->alerts.non_empty_audio_state_changed);
- cras_alert_destroy(g_observer->alerts.bt_battery_changed);
- cras_alert_destroy(
- g_observer->alerts.num_input_streams_with_permission);
- cras_alert_destroy(
- g_observer->alerts.num_active_streams[CRAS_STREAM_OUTPUT]);
- cras_alert_destroy(
- g_observer->alerts.num_active_streams[CRAS_STREAM_INPUT]);
- cras_alert_destroy(
- g_observer->alerts
- .num_active_streams[CRAS_STREAM_POST_MIX_PRE_DSP]);
- free(g_observer);
- g_observer = NULL;
-}
-
-int cras_observer_ops_are_empty(const struct cras_observer_ops *ops)
-{
- return memcmp(ops, &g_empty_ops, sizeof(*ops)) == 0;
-}
-
-void cras_observer_get_ops(const struct cras_observer_client *client,
- struct cras_observer_ops *ops)
-{
- if (!ops)
- return;
- if (!client)
- memset(ops, 0, sizeof(*ops));
- else
- memcpy(ops, &client->ops, sizeof(*ops));
-}
-
-void cras_observer_set_ops(struct cras_observer_client *client,
- const struct cras_observer_ops *ops)
-{
- if (!client)
- return;
- if (!ops)
- memset(&client->ops, 0, sizeof(client->ops));
- else
- memcpy(&client->ops, ops, sizeof(client->ops));
-}
-
-struct cras_observer_client *
-cras_observer_add(const struct cras_observer_ops *ops, void *context)
-{
- struct cras_observer_client *client;
-
- client = (struct cras_observer_client *)calloc(1, sizeof(*client));
- if (!client)
- return NULL;
- client->context = context;
- DL_APPEND(g_observer->clients, client);
- cras_observer_set_ops(client, ops);
- return client;
-}
-
-void cras_observer_remove(struct cras_observer_client *client)
-{
- if (!client)
- return;
- DL_DELETE(g_observer->clients, client);
- free(client);
-}
-
-/*
- * Public interface for notifiers.
- */
-
-void cras_observer_notify_output_volume(int32_t volume)
-{
- struct cras_observer_alert_data_volume data;
-
- data.volume = volume;
- cras_alert_pending_data(g_observer->alerts.output_volume, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_output_mute(int muted, int user_muted,
- int mute_locked)
-{
- struct cras_observer_alert_data_mute data;
-
- data.muted = muted;
- data.user_muted = user_muted;
- data.mute_locked = mute_locked;
- cras_alert_pending_data(g_observer->alerts.output_mute, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_capture_gain(int32_t gain)
-{
- struct cras_observer_alert_data_volume data;
-
- data.volume = gain;
- cras_alert_pending_data(g_observer->alerts.capture_gain, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_capture_mute(int muted, int mute_locked)
-{
- struct cras_observer_alert_data_mute data;
-
- data.muted = muted;
- data.user_muted = 0;
- data.mute_locked = mute_locked;
- cras_alert_pending_data(g_observer->alerts.capture_mute, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_nodes(void)
-{
- cras_alert_pending(g_observer->alerts.nodes);
-}
-
-void cras_observer_notify_active_node(enum CRAS_STREAM_DIRECTION dir,
- cras_node_id_t node_id)
-{
- struct cras_observer_alert_data_active_node data;
-
- data.direction = dir;
- data.node_id = node_id;
- cras_alert_pending_data(g_observer->alerts.active_node, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_output_node_volume(cras_node_id_t node_id,
- int32_t volume)
-{
- struct cras_observer_alert_data_node_volume data;
-
- data.node_id = node_id;
- data.volume = volume;
- cras_alert_pending_data(g_observer->alerts.output_node_volume, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_node_left_right_swapped(cras_node_id_t node_id,
- int swapped)
-{
- struct cras_observer_alert_data_node_lr_swapped data;
-
- data.node_id = node_id;
- data.swapped = swapped;
- cras_alert_pending_data(g_observer->alerts.node_left_right_swapped,
- &data, sizeof(data));
-}
-
-void cras_observer_notify_input_node_gain(cras_node_id_t node_id, int32_t gain)
-{
- struct cras_observer_alert_data_node_volume data;
-
- data.node_id = node_id;
- data.volume = gain;
- cras_alert_pending_data(g_observer->alerts.input_node_gain, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_suspend_changed(int suspended)
-{
- struct cras_observer_alert_data_suspend data;
-
- data.suspended = suspended;
- cras_alert_pending_data(g_observer->alerts.suspend_changed, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_num_active_streams(enum CRAS_STREAM_DIRECTION dir,
- uint32_t num_active_streams)
-{
- struct cras_observer_alert_data_streams data;
- struct cras_alert *alert;
-
- data.direction = dir;
- data.num_active_streams = num_active_streams;
- alert = g_observer->alerts.num_active_streams[dir];
- if (!alert)
- return;
-
- cras_alert_pending_data(alert, &data, sizeof(data));
-}
-
-void cras_observer_notify_input_streams_with_permission(
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE])
-{
- struct cras_observer_alert_data_input_streams data;
- struct cras_alert *alert;
-
- memcpy(&data.num_input_streams, num_input_streams,
- sizeof(*num_input_streams) * CRAS_NUM_CLIENT_TYPE);
- alert = g_observer->alerts.num_input_streams_with_permission;
- if (!alert)
- return;
-
- cras_alert_pending_data(alert, &data, sizeof(data));
-}
-
-void cras_observer_notify_hotword_triggered(int64_t tv_sec, int64_t tv_nsec)
-{
- struct cras_observer_alert_data_hotword_triggered data;
-
- data.tv_sec = tv_sec;
- data.tv_nsec = tv_nsec;
- cras_alert_pending_data(g_observer->alerts.hotword_triggered, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_non_empty_audio_state_changed(int non_empty)
-{
- struct cras_observer_non_empty_audio_state data;
-
- data.non_empty = non_empty;
-
- cras_alert_pending_data(
- g_observer->alerts.non_empty_audio_state_changed, &data,
- sizeof(data));
-}
-
-void cras_observer_notify_bt_battery_changed(const char *address,
- uint32_t level)
-{
- struct cras_observer_alert_data_bt_battery_changed data;
-
- data.address = address;
- data.level = level;
-
- cras_alert_pending_data(g_observer->alerts.bt_battery_changed, &data,
- sizeof(data));
-}