summaryrefslogtreecommitdiff
path: root/cras/src/server/cras_system_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/server/cras_system_state.c')
-rw-r--r--cras/src/server/cras_system_state.c714
1 files changed, 0 insertions, 714 deletions
diff --git a/cras/src/server/cras_system_state.c b/cras/src/server/cras_system_state.c
deleted file mode 100644
index 366afb5f..00000000
--- a/cras/src/server/cras_system_state.c
+++ /dev/null
@@ -1,714 +0,0 @@
-/* Copyright (c) 2012 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 <errno.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <syslog.h>
-
-#include "cras_alsa_card.h"
-#include "cras_alert.h"
-#include "cras_board_config.h"
-#include "cras_config.h"
-#include "cras_device_blocklist.h"
-#include "cras_iodev_list.h"
-#include "cras_observer.h"
-#include "cras_shm.h"
-#include "cras_system_state.h"
-#include "cras_tm.h"
-#include "cras_types.h"
-#include "cras_util.h"
-#include "utlist.h"
-
-struct card_list {
- struct cras_alsa_card *card;
- struct card_list *prev, *next;
-};
-
-struct name_list {
- char name[NAME_MAX];
- struct name_list *prev, *next;
-};
-
-/* The system state.
- * Members:
- * exp_state - The exported system state shared with clients.
- * shm_name - Name of posix shm region for exported state.
- * shm_fd - fd for shm area of system_state struct.
- * shm_fd_ro - fd for shm area of system_state struct, opened read-only.
- * This copy is to dup and pass to clients.
- * shm_size - Size of the shm area.
- * device_config_dir - Directory of device configs where volume curves live.
- * internal_ucm_suffix - The suffix to append to internal card name to
- * control which ucm config file to load.
- * device_blocklist - Blocklist of device the server will ignore.
- * cards - A list of active sound cards in the system.
- * update_lock - Protects the update_count, as audio threads can update the
- * stream count.
- * tm - The system-wide timer manager.
- * add_task - Function to handle adding a task for main thread to execute.
- * task_data - Data to be passed to add_task handler function.
- * main_thread_tid - The thread id of the main thread.
- * bt_fix_a2dp_packet_size - The flag to override A2DP packet size set by
- * Blueetoh peer devices to a smaller default value.
- */
-static struct {
- struct cras_server_state *exp_state;
- char shm_name[NAME_MAX];
- int shm_fd;
- int shm_fd_ro;
- size_t shm_size;
- const char *device_config_dir;
- const char *internal_ucm_suffix;
- struct name_list *ignore_suffix_cards;
- struct cras_device_blocklist *device_blocklist;
- struct card_list *cards;
- pthread_mutex_t update_lock;
- struct cras_tm *tm;
- /* Select loop callback registration. */
- int (*fd_add)(int fd, void (*cb)(void *data, int events), void *cb_data,
- int events, void *select_data);
- void (*fd_rm)(int fd, void *select_data);
- void *select_data;
- int (*add_task)(void (*callback)(void *data), void *callback_data,
- void *task_data);
- void *task_data;
- struct cras_audio_thread_snapshot_buffer snapshot_buffer;
- pthread_t main_thread_tid;
- bool bt_fix_a2dp_packet_size;
-} state;
-
-/* The string format is CARD1,CARD2,CARD3. Divide it into a list. */
-void init_ignore_suffix_cards(char *str)
-{
- struct name_list *card;
- char *ptr;
-
- state.ignore_suffix_cards = NULL;
-
- if (str == NULL)
- return;
-
- ptr = strtok(str, ",");
- while (ptr != NULL) {
- card = (struct name_list *)calloc(1, sizeof(*card));
- if (!card) {
- syslog(LOG_ERR, "Failed to call calloc: %d", errno);
- return;
- }
- strncpy(card->name, ptr, NAME_MAX - 1);
- DL_APPEND(state.ignore_suffix_cards, card);
- ptr = strtok(NULL, ",");
- }
-}
-
-void deinit_ignore_suffix_cards()
-{
- struct name_list *card;
- DL_FOREACH (state.ignore_suffix_cards, card) {
- DL_DELETE(state.ignore_suffix_cards, card);
- free(card);
- }
-}
-
-/*
- * Exported Interface.
- */
-
-void cras_system_state_init(const char *device_config_dir, const char *shm_name,
- int rw_shm_fd, int ro_shm_fd,
- struct cras_server_state *exp_state,
- size_t exp_state_size)
-{
- struct cras_board_config board_config;
- int rc;
-
- assert(sizeof(*exp_state) == exp_state_size);
- state.shm_size = sizeof(*exp_state);
-
- strncpy(state.shm_name, shm_name, sizeof(state.shm_name));
- state.shm_name[sizeof(state.shm_name) - 1] = '\0';
- state.shm_fd = rw_shm_fd;
- state.shm_fd_ro = ro_shm_fd;
-
- /* Read board config. */
- memset(&board_config, 0, sizeof(board_config));
- cras_board_config_get(device_config_dir, &board_config);
-
- /* Initial system state. */
- exp_state->state_version = CRAS_SERVER_STATE_VERSION;
- exp_state->volume = CRAS_MAX_SYSTEM_VOLUME;
- exp_state->mute = 0;
- exp_state->mute_locked = 0;
- exp_state->suspended = 0;
- exp_state->capture_mute = 0;
- exp_state->capture_mute_locked = 0;
- exp_state->min_volume_dBFS = DEFAULT_MIN_VOLUME_DBFS;
- exp_state->max_volume_dBFS = DEFAULT_MAX_VOLUME_DBFS;
- exp_state->num_streams_attached = 0;
- exp_state->default_output_buffer_size =
- board_config.default_output_buffer_size;
- exp_state->aec_supported = board_config.aec_supported;
- exp_state->aec_group_id = board_config.aec_group_id;
- exp_state->bt_wbs_enabled = board_config.bt_wbs_enabled;
- exp_state->deprioritize_bt_wbs_mic =
- board_config.deprioritize_bt_wbs_mic;
- exp_state->noise_cancellation_enabled = 0;
- exp_state->hotword_pause_at_suspend =
- board_config.hotword_pause_at_suspend;
-
- if ((rc = pthread_mutex_init(&state.update_lock, 0) != 0)) {
- syslog(LOG_ERR, "Fatal: system state mutex init");
- exit(rc);
- }
-
- state.exp_state = exp_state;
-
- /* Directory for volume curve configs.
- * Note that device_config_dir does not affect device blocklist.
- * Device blocklist is common to all boards so we do not need
- * to change device blocklist at run time. */
- state.device_config_dir = device_config_dir;
- state.internal_ucm_suffix = NULL;
- init_ignore_suffix_cards(board_config.ucm_ignore_suffix);
- free(board_config.ucm_ignore_suffix);
-
- state.tm = cras_tm_init();
- if (!state.tm) {
- syslog(LOG_ERR, "Fatal: system state timer init");
- exit(-ENOMEM);
- }
-
- /* Read config file for blocklisted devices. */
- state.device_blocklist =
- cras_device_blocklist_create(CRAS_CONFIG_FILE_DIR);
-
- /* Initialize snapshot buffer memory */
- memset(&state.snapshot_buffer, 0,
- sizeof(struct cras_audio_thread_snapshot_buffer));
-
- /* Save thread id of the main thread. */
- state.main_thread_tid = pthread_self();
-
- state.bt_fix_a2dp_packet_size = false;
-}
-
-void cras_system_state_set_internal_ucm_suffix(const char *internal_ucm_suffix)
-{
- state.internal_ucm_suffix = internal_ucm_suffix;
-}
-
-void cras_system_state_deinit()
-{
- /* Free any resources used. This prevents unit tests from leaking. */
-
- cras_device_blocklist_destroy(state.device_blocklist);
-
- cras_tm_deinit(state.tm);
-
- if (state.exp_state) {
- munmap(state.exp_state, state.shm_size);
- cras_shm_close_unlink(state.shm_name, state.shm_fd);
- if (state.shm_fd_ro != state.shm_fd)
- close(state.shm_fd_ro);
- }
-
- deinit_ignore_suffix_cards();
- pthread_mutex_destroy(&state.update_lock);
-}
-
-void cras_system_set_volume(size_t volume)
-{
- if (volume > CRAS_MAX_SYSTEM_VOLUME)
- syslog(LOG_DEBUG, "system volume set out of range %zu", volume);
-
- state.exp_state->volume = MIN(volume, CRAS_MAX_SYSTEM_VOLUME);
- cras_observer_notify_output_volume(state.exp_state->volume);
-}
-
-size_t cras_system_get_volume()
-{
- return state.exp_state->volume;
-}
-
-void cras_system_notify_mute(void)
-{
- cras_observer_notify_output_mute(state.exp_state->mute,
- state.exp_state->user_mute,
- state.exp_state->mute_locked);
-}
-
-void cras_system_set_user_mute(int mute)
-{
- int current_mute = cras_system_get_mute();
-
- if (state.exp_state->user_mute == !!mute)
- return;
-
- state.exp_state->user_mute = !!mute;
-
- if (current_mute == (mute || state.exp_state->mute))
- return;
-
- cras_system_notify_mute();
-}
-
-void cras_system_set_mute(int mute)
-{
- int current_mute = cras_system_get_mute();
-
- if (state.exp_state->mute_locked)
- return;
-
- if (state.exp_state->mute == !!mute)
- return;
-
- state.exp_state->mute = !!mute;
-
- if (current_mute == (mute || state.exp_state->user_mute))
- return;
-
- cras_system_notify_mute();
-}
-
-void cras_system_set_mute_locked(int locked)
-{
- if (state.exp_state->mute_locked == !!locked)
- return;
-
- state.exp_state->mute_locked = !!locked;
-}
-
-int cras_system_get_mute()
-{
- return state.exp_state->mute || state.exp_state->user_mute;
-}
-
-int cras_system_get_user_mute()
-{
- return state.exp_state->user_mute;
-}
-
-int cras_system_get_system_mute()
-{
- return state.exp_state->mute;
-}
-
-int cras_system_get_mute_locked()
-{
- return state.exp_state->mute_locked;
-}
-
-void cras_system_notify_capture_mute(void)
-{
- cras_observer_notify_capture_mute(state.exp_state->capture_mute,
- state.exp_state->capture_mute_locked);
-}
-
-void cras_system_set_capture_mute(int mute)
-{
- if (state.exp_state->capture_mute_locked)
- return;
-
- state.exp_state->capture_mute = !!mute;
- cras_system_notify_capture_mute();
-}
-
-void cras_system_set_capture_mute_locked(int locked)
-{
- state.exp_state->capture_mute_locked = !!locked;
- cras_system_notify_capture_mute();
-}
-
-int cras_system_get_capture_mute()
-{
- return state.exp_state->capture_mute;
-}
-
-int cras_system_get_capture_mute_locked()
-{
- return state.exp_state->capture_mute_locked;
-}
-
-int cras_system_get_suspended()
-{
- return state.exp_state->suspended;
-}
-
-void cras_system_set_suspended(int suspended)
-{
- state.exp_state->suspended = suspended;
- cras_observer_notify_suspend_changed(suspended);
- cras_alert_process_all_pending_alerts();
-}
-
-void cras_system_set_volume_limits(long min, long max)
-{
- state.exp_state->min_volume_dBFS = min;
- state.exp_state->max_volume_dBFS = max;
-}
-
-long cras_system_get_min_volume()
-{
- return state.exp_state->min_volume_dBFS;
-}
-
-long cras_system_get_max_volume()
-{
- return state.exp_state->max_volume_dBFS;
-}
-
-int cras_system_get_default_output_buffer_size()
-{
- return state.exp_state->default_output_buffer_size;
-}
-
-int cras_system_get_aec_supported()
-{
- return state.exp_state->aec_supported;
-}
-
-int cras_system_get_aec_group_id()
-{
- return state.exp_state->aec_group_id;
-}
-
-void cras_system_set_bt_wbs_enabled(bool enabled)
-{
- state.exp_state->bt_wbs_enabled = enabled;
-}
-
-bool cras_system_get_bt_wbs_enabled()
-{
- return !!state.exp_state->bt_wbs_enabled;
-}
-
-bool cras_system_get_deprioritize_bt_wbs_mic()
-{
- return !!state.exp_state->deprioritize_bt_wbs_mic;
-}
-
-void cras_system_set_bt_fix_a2dp_packet_size_enabled(bool enabled)
-{
- state.bt_fix_a2dp_packet_size = enabled;
-}
-
-bool cras_system_get_bt_fix_a2dp_packet_size_enabled()
-{
- return state.bt_fix_a2dp_packet_size;
-}
-
-void cras_system_set_noise_cancellation_enabled(bool enabled)
-{
- /* When the flag is toggled, propagate to all iodevs immediately. */
- if (cras_system_get_noise_cancellation_enabled() != enabled) {
- state.exp_state->noise_cancellation_enabled = enabled;
- cras_iodev_list_reset_for_noise_cancellation();
- }
-}
-
-bool cras_system_get_noise_cancellation_enabled()
-{
- return !!state.exp_state->noise_cancellation_enabled;
-}
-
-bool cras_system_check_ignore_ucm_suffix(const char *card_name)
-{
- /* Check the general case: ALSA Loopback card "Loopback". */
- if (!strcmp("Loopback", card_name))
- return true;
-
- /* Check board-specific ignore ucm suffix cards. */
- struct name_list *card;
- DL_FOREACH (state.ignore_suffix_cards, card) {
- if (!strcmp(card->name, card_name))
- return true;
- }
- return false;
-}
-
-bool cras_system_get_hotword_pause_at_suspend()
-{
- return !!state.exp_state->hotword_pause_at_suspend;
-}
-
-void cras_system_set_hotword_pause_at_suspend(bool pause)
-{
- state.exp_state->hotword_pause_at_suspend = pause;
-}
-
-int cras_system_add_alsa_card(struct cras_alsa_card_info *alsa_card_info)
-{
- struct card_list *card;
- struct cras_alsa_card *alsa_card;
- unsigned card_index;
-
- if (alsa_card_info == NULL)
- return -EINVAL;
-
- card_index = alsa_card_info->card_index;
-
- DL_FOREACH (state.cards, card) {
- if (card_index == cras_alsa_card_get_index(card->card))
- return -EEXIST;
- }
- alsa_card =
- cras_alsa_card_create(alsa_card_info, state.device_config_dir,
- state.device_blocklist,
- state.internal_ucm_suffix);
- if (alsa_card == NULL)
- return -ENOMEM;
- card = calloc(1, sizeof(*card));
- if (card == NULL)
- return -ENOMEM;
- card->card = alsa_card;
- DL_APPEND(state.cards, card);
- return 0;
-}
-
-int cras_system_remove_alsa_card(size_t alsa_card_index)
-{
- struct card_list *card;
-
- DL_FOREACH (state.cards, card) {
- if (alsa_card_index == cras_alsa_card_get_index(card->card))
- break;
- }
- if (card == NULL)
- return -EINVAL;
- DL_DELETE(state.cards, card);
- cras_alsa_card_destroy(card->card);
- free(card);
- return 0;
-}
-
-int cras_system_alsa_card_exists(unsigned alsa_card_index)
-{
- struct card_list *card;
-
- DL_FOREACH (state.cards, card)
- if (alsa_card_index == cras_alsa_card_get_index(card->card))
- return 1;
- return 0;
-}
-
-int cras_system_set_select_handler(
- int (*add)(int fd, void (*callback)(void *data, int events),
- void *callback_data, int events, void *select_data),
- void (*rm)(int fd, void *select_data), void *select_data)
-{
- if (state.fd_add != NULL || state.fd_rm != NULL)
- return -EEXIST;
- state.fd_add = add;
- state.fd_rm = rm;
- state.select_data = select_data;
- return 0;
-}
-
-int cras_system_add_select_fd(int fd, void (*callback)(void *data, int revents),
- void *callback_data, int events)
-{
- if (state.fd_add == NULL)
- return -EINVAL;
- return state.fd_add(fd, callback, callback_data, events,
- state.select_data);
-}
-
-int cras_system_set_add_task_handler(int (*add_task)(void (*cb)(void *data),
- void *callback_data,
- void *task_data),
- void *task_data)
-{
- if (state.add_task != NULL)
- return -EEXIST;
-
- state.add_task = add_task;
- state.task_data = task_data;
- return 0;
-}
-
-int cras_system_add_task(void (*callback)(void *data), void *callback_data)
-{
- if (state.add_task == NULL)
- return -EINVAL;
-
- return state.add_task(callback, callback_data, state.task_data);
-}
-
-void cras_system_rm_select_fd(int fd)
-{
- if (state.fd_rm != NULL)
- state.fd_rm(fd, state.select_data);
-}
-
-void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type)
-{
- struct cras_server_state *s;
-
- s = cras_system_state_update_begin();
- if (!s)
- return;
-
- s->num_active_streams[direction]++;
- s->num_streams_attached++;
- if (direction == CRAS_STREAM_INPUT) {
- s->num_input_streams_with_permission[client_type]++;
- cras_observer_notify_input_streams_with_permission(
- s->num_input_streams_with_permission);
- }
-
- cras_system_state_update_complete();
- cras_observer_notify_num_active_streams(
- direction, s->num_active_streams[direction]);
-}
-
-void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type)
-{
- struct cras_server_state *s;
- unsigned i, sum;
-
- s = cras_system_state_update_begin();
- if (!s)
- return;
-
- sum = 0;
- for (i = 0; i < CRAS_NUM_DIRECTIONS; i++)
- sum += s->num_active_streams[i];
-
- /* Set the last active time when removing the final stream. */
- if (sum == 1)
- cras_clock_gettime(CLOCK_MONOTONIC_RAW,
- &s->last_active_stream_time);
- s->num_active_streams[direction]--;
- if (direction == CRAS_STREAM_INPUT) {
- s->num_input_streams_with_permission[client_type]--;
- cras_observer_notify_input_streams_with_permission(
- s->num_input_streams_with_permission);
- }
-
- cras_system_state_update_complete();
- cras_observer_notify_num_active_streams(
- direction, s->num_active_streams[direction]);
-}
-
-unsigned cras_system_state_get_active_streams()
-{
- unsigned i, sum;
- sum = 0;
- for (i = 0; i < CRAS_NUM_DIRECTIONS; i++)
- sum += state.exp_state->num_active_streams[i];
- return sum;
-}
-
-unsigned cras_system_state_get_active_streams_by_direction(
- enum CRAS_STREAM_DIRECTION direction)
-{
- return state.exp_state->num_active_streams[direction];
-}
-
-void cras_system_state_get_input_streams_with_permission(
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE])
-{
- unsigned type;
- for (type = 0; type < CRAS_NUM_CLIENT_TYPE; ++type)
- num_input_streams[type] =
- state.exp_state->num_input_streams_with_permission[type];
-}
-
-void cras_system_state_get_last_stream_active_time(struct cras_timespec *ts)
-{
- *ts = state.exp_state->last_active_stream_time;
-}
-
-int cras_system_state_get_output_devs(const struct cras_iodev_info **devs)
-{
- *devs = state.exp_state->output_devs;
- return state.exp_state->num_output_devs;
-}
-
-int cras_system_state_get_input_devs(const struct cras_iodev_info **devs)
-{
- *devs = state.exp_state->input_devs;
- return state.exp_state->num_input_devs;
-}
-
-int cras_system_state_get_output_nodes(const struct cras_ionode_info **nodes)
-{
- *nodes = state.exp_state->output_nodes;
- return state.exp_state->num_output_nodes;
-}
-
-int cras_system_state_get_input_nodes(const struct cras_ionode_info **nodes)
-{
- *nodes = state.exp_state->input_nodes;
- return state.exp_state->num_input_nodes;
-}
-
-void cras_system_state_set_non_empty_status(int non_empty)
-{
- state.exp_state->non_empty_status = non_empty;
-}
-
-int cras_system_state_get_non_empty_status()
-{
- return state.exp_state->non_empty_status;
-}
-
-struct cras_server_state *cras_system_state_update_begin()
-{
- if (pthread_mutex_lock(&state.update_lock)) {
- syslog(LOG_ERR, "Failed to lock stream mutex");
- return NULL;
- }
-
- __sync_fetch_and_add(&state.exp_state->update_count, 1);
- return state.exp_state;
-}
-
-void cras_system_state_update_complete()
-{
- __sync_fetch_and_add(&state.exp_state->update_count, 1);
- pthread_mutex_unlock(&state.update_lock);
-}
-
-struct cras_server_state *cras_system_state_get_no_lock()
-{
- return state.exp_state;
-}
-
-key_t cras_sys_state_shm_fd()
-{
- return state.shm_fd_ro;
-}
-
-struct cras_tm *cras_system_state_get_tm()
-{
- return state.tm;
-}
-
-void cras_system_state_dump_snapshots()
-{
- memcpy(&state.exp_state->snapshot_buffer, &state.snapshot_buffer,
- sizeof(struct cras_audio_thread_snapshot_buffer));
-}
-
-void cras_system_state_add_snapshot(struct cras_audio_thread_snapshot *snapshot)
-{
- state.snapshot_buffer.snapshots[state.snapshot_buffer.pos++] =
- (*snapshot);
- state.snapshot_buffer.pos %= CRAS_MAX_AUDIO_THREAD_SNAPSHOTS;
-}
-
-int cras_system_state_in_main_thread()
-{
- return pthread_self() == state.main_thread_tid;
-}