From 5bac99be4f7669ca1b235e2f399b3840cc925991 Mon Sep 17 00:00:00 2001 From: Seonmi Jin Date: Fri, 18 Sep 2015 17:41:08 +0900 Subject: [PATCH] Removed modules regarding tizen platform move to pulseaudio-modules-tizen pkg [Version] 5.0-41 [Profile] Common [Dependency module] pulseaudio-modules-tizen [Dependency commit] d4d9b738bb1645f13a89bab176321a7fe525073c Change-Id: I395fad1e6f950eedc3c4545d49914ca674169418 Signed-off-by: Seonmi Jin --- packaging/pulseaudio.spec | 7 +- src/Makefile.am | 39 +- src/modules/module-sound-player.c | 626 ---- src/modules/tizen/communicator.c | 90 - src/modules/tizen/communicator.h | 21 - src/modules/tizen/device-manager.c | 4277 ------------------------ src/modules/tizen/device-manager.h | 75 - src/modules/tizen/hal-manager.c | 312 -- src/modules/tizen/hal-manager.h | 64 - src/modules/tizen/module-policy.c | 1544 --------- src/modules/tizen/module-tizenaudio-sink.c | 480 --- src/modules/tizen/stream-manager-priv.h | 98 - src/modules/tizen/stream-manager-volume-priv.h | 30 - src/modules/tizen/stream-manager-volume.c | 858 ----- src/modules/tizen/stream-manager-volume.h | 14 - src/modules/tizen/stream-manager.c | 2632 --------------- src/modules/tizen/stream-manager.h | 51 - 17 files changed, 3 insertions(+), 11215 deletions(-) delete mode 100644 src/modules/module-sound-player.c delete mode 100644 src/modules/tizen/communicator.c delete mode 100644 src/modules/tizen/communicator.h delete mode 100644 src/modules/tizen/device-manager.c delete mode 100644 src/modules/tizen/device-manager.h delete mode 100644 src/modules/tizen/hal-manager.c delete mode 100644 src/modules/tizen/hal-manager.h delete mode 100644 src/modules/tizen/module-policy.c delete mode 100644 src/modules/tizen/module-tizenaudio-sink.c delete mode 100644 src/modules/tizen/stream-manager-priv.h delete mode 100644 src/modules/tizen/stream-manager-volume-priv.h delete mode 100644 src/modules/tizen/stream-manager-volume.c delete mode 100644 src/modules/tizen/stream-manager-volume.h delete mode 100644 src/modules/tizen/stream-manager.c delete mode 100644 src/modules/tizen/stream-manager.h diff --git a/packaging/pulseaudio.spec b/packaging/pulseaudio.spec index c94a2a6..5943502 100644 --- a/packaging/pulseaudio.spec +++ b/packaging/pulseaudio.spec @@ -11,7 +11,7 @@ Name: pulseaudio Summary: Improved Linux sound server Version: 5.0 -Release: 40 +Release: 41 Group: Multimedia/Audio License: GPL-2.0+ and LGPL-2.1+ URL: http://pulseaudio.org @@ -376,7 +376,6 @@ fi %{_libdir}/pulse-%{version}/modules/libtunnel-manager.so %{_libdir}/pulse-%{version}/modules/module-alsa-sink.so %{_libdir}/pulse-%{version}/modules/module-alsa-source.so -%{_libdir}/pulse-%{version}/modules/module-tizenaudio-sink.so %{_libdir}/pulse-%{version}/modules/module-always-sink.so %{_libdir}/pulse-%{version}/modules/module-console-kit.so %{_libdir}/pulse-%{version}/modules/module-device-restore.so @@ -440,15 +439,11 @@ fi %{_unitdir_user}/pulseaudio.socket %{_unitdir}/pulseaudio.service %{_unitdir}/multi-user.target.wants/pulseaudio.service -%if %{with pulseaudio_samsung_policy} -%{_libdir}/pulse-%{version}/modules/module-policy.so -%endif %{_libdir}/pulse-%{version}/modules/libvolume-api.so %{_libdir}/pulse-%{version}/modules/libmain-volume-policy.so %{_libdir}/pulse-%{version}/modules/module-volume-api.so %{_libdir}/pulse-%{version}/modules/module-main-volume-policy.so %{_libdir}/pulse-%{version}/modules/module-audio-groups.so -%{_libdir}/pulse-%{version}/modules/module-sound-player.so %config(noreplace) /etc/bash_completion.d/pulseaudio-bash-completion.sh diff --git a/src/Makefile.am b/src/Makefile.am index 30bff0a..42a57d9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1325,10 +1325,6 @@ if HAVE_DBUS # Serveral module (e.g. libalsa-util.la) modlibexec_LTLIBRARIES += \ module-console-kit.la -if USE_SAMSUNG_POLICY -modlibexec_LTLIBRARIES += \ - module-policy.la -endif endif modlibexec_LTLIBRARIES += \ module-cli.la \ @@ -1377,9 +1373,7 @@ modlibexec_LTLIBRARIES += \ module-filter-apply.la \ module-filter-heuristics.la \ module-role-ducking.la \ - module-audio-groups.la \ - module-sound-player.la \ - module-tizenaudio-sink.la + module-audio-groups.la if HAVE_ESOUND modlibexec_LTLIBRARIES += \ @@ -1672,7 +1666,6 @@ SYMDEF_FILES = \ module-alsa-sink-symdef.h \ module-alsa-source-symdef.h \ module-alsa-card-symdef.h \ - module-tizenaudio-sink-symdef.h \ module-coreaudio-detect-symdef.h \ module-coreaudio-device-symdef.h \ module-solaris-symdef.h \ @@ -1720,13 +1713,8 @@ SYMDEF_FILES = \ module-switch-on-port-available-symdef.h \ module-filter-apply-symdef.h \ module-filter-heuristics-symdef.h \ - module-audio-groups-symdef.h \ - module-sound-player-symdef.h + module-audio-groups-symdef.h -if USE_SAMSUNG_POLICY -SYMDEF_FILES += \ - module-policy-symdef.h -endif if HAVE_ESOUND SYMDEF_FILES += \ module-esound-protocol-tcp-symdef.h \ @@ -2071,11 +2059,6 @@ module_alsa_card_la_LDFLAGS = $(MODULE_LDFLAGS) module_alsa_card_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la module_alsa_card_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) -module_tizenaudio_sink_la_SOURCES = modules/tizen/module-tizenaudio-sink.c -module_tizenaudio_sink_la_LDFLAGS = $(MODULE_LDFLAGS) -module_tizenaudio_sink_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) -module_tizenaudio_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS) - # Solaris module_solaris_la_SOURCES = modules/module-solaris.c @@ -2421,24 +2404,6 @@ module_rygel_media_server_la_LDFLAGS = $(MODULE_LDFLAGS) module_rygel_media_server_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) libprotocol-http.la module_rygel_media_server_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -if USE_SAMSUNG_POLICY -module_policy_la_SOURCES = \ - modules/tizen/module-policy.c \ - modules/tizen/communicator.c modules/tizen/communicator.h \ - modules/tizen/hal-manager.c modules/tizen/hal-manager.h \ - modules/tizen/stream-manager.c modules/tizen/stream-manager.h modules/tizen/stream-manager-priv.h \ - modules/tizen/stream-manager-volume.c modules/tizen/stream-manager-volume.h modules/tizen/stream-manager-volume-priv.h \ - modules/tizen/device-manager.c modules/tizen/device-manager.h -module_policy_la_LDFLAGS = $(MODULE_LDFLAGS) -module_policy_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(LIBJSON_LIBS) $(ASOUNDLIB_LIBS) libprotocol-native.la libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la -module_policy_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) $(INIPARSER_CFLAGS) $(LIBJSON_CFLAGS) $(ASOUNDLIB_CFLAGS) -endif - -module_sound_player_la_SOURCES = modules/module-sound-player.c -module_sound_player_la_LDFLAGS = $(MODULE_LDFLAGS) -module_sound_player_la_LIBADD = $(MODULE_LIBADD) $(AM_LIBADD) $(DBUS_LIBS) -module_sound_player_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) - ################################### # Some minor stuff # ################################### diff --git a/src/modules/module-sound-player.c b/src/modules/module-sound-player.c deleted file mode 100644 index 9f98543..0000000 --- a/src/modules/module-sound-player.c +++ /dev/null @@ -1,626 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2014 Sangchul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_DBUS -#include -#include -#include -#endif - -#include "module-sound-player-symdef.h" - -#include - -PA_MODULE_AUTHOR("Sangchul Lee"); -PA_MODULE_DESCRIPTION("Sound Player module"); -PA_MODULE_VERSION(PACKAGE_VERSION); -PA_MODULE_LOAD_ONCE(TRUE); - -#ifdef HAVE_DBUS -#define ARR_ARG_MAX 32 -#define SOUND_PLAYER_OBJECT_PATH "/org/pulseaudio/SoundPlayer" -#define SOUND_PLAYER_INTERFACE "org.pulseaudio.SoundPlayer" -#define SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY "SimplePlay" -#define SOUND_PLAYER_METHOD_NAME_SAMPLE_PLAY "SamplePlay" -#define SOUND_PLAYER_SIGNAL_EOS "EOS" - -static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m, void *userdata); -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata); -static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_simple_play(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_sample_play(DBusConnection *conn, DBusMessage *msg, void *userdata); - -enum method_handler_index { - METHOD_HANDLER_SIMPLE_PLAY, - METHOD_HANDLER_SAMPLE_PLAY, - METHOD_HANDLER_MAX -}; - -static pa_dbus_arg_info simple_play_args[] = { { "uri", "s", "in" }, - { "role", "s", "in" }, - { "volume_gain", "s", "in" }}; -static pa_dbus_arg_info sample_play_args[] = { { "sample_name", "s", "in" }, - { "role", "s", "in" }, - { "volume_gain", "s", "in" }}; - -static const char* signature_args_for_in[] = { "sss", "sss" }; - -static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { - [METHOD_HANDLER_SIMPLE_PLAY] = { - .method_name = SOUND_PLAYER_METHOD_NAME_SIMPLE_PLAY, - .arguments = simple_play_args, - .n_arguments = sizeof(simple_play_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_simple_play }, - [METHOD_HANDLER_SAMPLE_PLAY] = { - .method_name = SOUND_PLAYER_METHOD_NAME_SAMPLE_PLAY, - .arguments = sample_play_args, - .n_arguments = sizeof(sample_play_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_sample_play } -}; - -#ifdef USE_DBUS_PROTOCOL - -static pa_dbus_interface_info sound_player_interface_info = { - .name = SOUND_PLAYER_INTERFACE, - .method_handlers = method_handlers, - .n_method_handlers = METHOD_HANDLER_MAX, - .property_handlers = , - .n_property_handlers = , - .get_all_properties_cb =, - .signals =, - .n_signals = -}; - -#else - -#define SOUND_PLAYER_INTROSPECT_XML \ - DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ - "" \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - "" -#endif - -#endif - -static void io_event_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata); - -struct userdata { - int fd; - pa_io_event *io; - pa_module *module; - pa_hook_slot *sink_input_unlink_slot; -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - pa_dbus_protocol *dbus_protocol; -#else - pa_dbus_connection *dbus_conn; -#endif - pa_idxset *stream_idxs; -#endif -}; - -#define FILE_FULL_PATH 1024 /* File path length */ -#define ROLE_NAME_LEN 64 /* Role name length */ -#define VOLUME_GAIN_TYPE_LEN 64 /* Volume gain type length */ -#define RETRY_NUM 100 - -struct ipc_data { - char filename[FILE_FULL_PATH]; - char role[ROLE_NAME_LEN]; - char volume_gain_type[VOLUME_GAIN_TYPE_LEN]; -}; - -#define KEYTONE_PATH "/tmp/keytone" /* Keytone pipe path */ -#define KEYTONE_GROUP 6526 /* Keytone group : assigned by security */ -#define DEFAULT_IPC_TYPE IPC_TYPE_PIPE - -#define MAX_NAME_LEN 256 -static int _simple_play(struct userdata *u, const char *file_path, const char *role, const char *vol_gain_type) { - int ret = 0; - pa_sink *sink = NULL; - pa_proplist *p; - const char *name_prefix = "SIMPLE_PLAY"; - - char name[MAX_NAME_LEN] = {0}; - - uint32_t stream_idx = 0; - uint32_t scache_idx = 0; - - p = pa_proplist_new(); - - /* Set role type of stream */ - if (role) - pa_proplist_sets(p, PA_PROP_MEDIA_ROLE, role); - - /* Set volume gain type of stream */ - if (vol_gain_type) - pa_proplist_sets(p, PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE, vol_gain_type); - - sink = pa_namereg_get_default_sink(u->module->core); - - pa_log_debug("role[%s], volume_gain_type[%s]", role, vol_gain_type); - snprintf(name, sizeof(name)-1, "%s_%s", name_prefix, file_path); - scache_idx = pa_scache_get_id_by_name(u->module->core, name); - if (scache_idx != PA_IDXSET_INVALID) { - pa_log_debug("found cached index [%u] for name [%s]", scache_idx, file_path); - } else { - /* for more precision, need to update volume value here */ - if ((ret = pa_scache_add_file_lazy(u->module->core, name, file_path, &scache_idx)) != 0) { - pa_log_error("failed to add file [%s]", file_path); - goto exit; - } else { - pa_log_debug("success to add file [%s], index [%u]", file_path, scache_idx); - } - } - - pa_log_debug("pa_scache_play_item() start"); - ret = pa_scache_play_item(u->module->core, name, sink, PA_VOLUME_NORM, p, &stream_idx); - if (ret < 0) { - pa_log_error("pa_scache_play_item fail, ret[%d]", ret); - goto exit; - } - pa_log_debug("pa_scache_play_item() end, stream_idx(%u)", stream_idx); - - if (!ret) - ret = (int32_t)stream_idx; -exit: - pa_proplist_free(p); - return ret; -} - -static int _sample_play(struct userdata *u, const char *sample_name, const char *role, const char *vol_gain_type) { - int ret = 0; - pa_sink *sink = NULL; - pa_proplist *p; - - uint32_t stream_idx = 0; - uint32_t scache_idx = 0; - - p = pa_proplist_new(); - - /* Set role type of stream */ - if (role) - pa_proplist_sets(p, PA_PROP_MEDIA_ROLE, role); - - /* Set volume gain type of stream */ - if (vol_gain_type) - pa_proplist_sets(p, PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE, vol_gain_type); - - sink = pa_namereg_get_default_sink(u->module->core); - - pa_log_debug("role[%s], volume_gain_type[%s]", role, vol_gain_type); - - scache_idx = pa_scache_get_id_by_name(u->module->core, sample_name); - if (scache_idx != PA_IDXSET_INVALID) { - pa_log_debug("pa_scache_play_item() start, scache idx[%u] for name[%s]", scache_idx, sample_name); - /* for more precision, need to update volume value here */ - if ((ret = pa_scache_play_item(u->module->core, sample_name, sink, PA_VOLUME_NORM, p, &stream_idx) < 0)) { - pa_log_error("pa_scache_play_item fail"); - goto exit; - } - pa_log_debug("pa_scache_play_item() end, stream_idx(%u)", stream_idx); - } else - pa_log_error("could not find the scache item for [%s]", sample_name); - - if (!ret) - ret = (int32_t)stream_idx; -exit: - pa_proplist_free(p); - return ret; -} - -#ifdef HAVE_DBUS -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *xml = SOUND_PLAYER_INTROSPECT_XML; - DBusMessage *r = NULL; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se(r = dbus_message_new_method_return(msg)); - pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)); - - if (r) { - pa_assert_se(dbus_connection_send((conn), r, NULL)); - dbus_message_unref(r); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void handle_simple_play(DBusConnection *conn, DBusMessage *msg, void *userdata) { - char *uri = NULL; - char *role = NULL; - char *volume_gain = NULL; - dbus_int32_t result = 0; - struct userdata *u = (struct userdata*)userdata; - pa_assert(conn); - pa_assert(msg); - pa_assert(u); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &uri, - DBUS_TYPE_STRING, &role, - DBUS_TYPE_STRING, &volume_gain, - DBUS_TYPE_INVALID)); - pa_log_info("uri[%s], role[%s], volume_gain[%s]", uri, role, volume_gain); - if (uri) - result = _simple_play(u, uri, role, volume_gain); - else - result = -1; - - if (result != -1) { - uint32_t idx = 0; - int32_t *stream_idx = NULL; - stream_idx = pa_xmalloc0(sizeof(int32_t)); - *stream_idx = result; - pa_idxset_put(u->stream_idxs, stream_idx, &idx); - } - pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_INT32, &result); -} - -static void handle_sample_play(DBusConnection *conn, DBusMessage *msg, void *userdata) { - char *sample_name = NULL; - char *role = NULL; - char *volume_gain = NULL; - dbus_int32_t result = 0; - struct userdata *u = (struct userdata*)userdata; - pa_assert(conn); - pa_assert(msg); - pa_assert(u); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &sample_name, - DBUS_TYPE_STRING, &role, - DBUS_TYPE_STRING, &volume_gain, - DBUS_TYPE_INVALID)); - pa_log_info("sample_name[%s], role[%s], volume_gain[%s]", sample_name, role, volume_gain); - if (sample_name) - result = _sample_play(u, sample_name, role, volume_gain); - else - result = -1; - - if (result != -1) { - uint32_t idx = 0; - int32_t *stream_idx = NULL; - stream_idx = pa_xmalloc0(sizeof(int32_t)); - *stream_idx = result; - pa_idxset_put(u->stream_idxs, stream_idx, &idx); - } - - pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_INT32, &result); -} - -static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) { - int idx = 0; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - for (idx = 0; idx < METHOD_HANDLER_MAX; idx++) { - if (dbus_message_is_method_call(msg, SOUND_PLAYER_INTERFACE, method_handlers[idx].method_name )) { - if (pa_streq(dbus_message_get_signature(msg), signature_args_for_in[idx])) { - method_handlers[idx].receive_cb(conn, msg, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } else { - pa_log_warn("Wrong Argument Signature"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_SIGNATURE, "Wrong Signature, Expected %s", signature_args_for_in[idx]); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - } - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m, void *userdata) { - struct userdata *u = userdata; - const char *path, *interface, *member; - - pa_assert(c); - pa_assert(m); - pa_assert(u); - - path = dbus_message_get_path(m); - interface = dbus_message_get_interface(m); - member = dbus_message_get_member(m); - - pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member); - - if (!pa_streq(path, SOUND_PLAYER_OBJECT_PATH)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { - return handle_introspect(c, m, u); - } else { - return handle_methods(c, m, u); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void send_signal_for_eos(struct userdata *u, int32_t stream_idx) { - DBusMessage *signal_msg = NULL; - - pa_assert(u); - - pa_log_debug("Send EOS signal for stream_idx(%d)", stream_idx); - - pa_assert_se(signal_msg = dbus_message_new_signal(SOUND_PLAYER_OBJECT_PATH, SOUND_PLAYER_INTERFACE, SOUND_PLAYER_SIGNAL_EOS)); - pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_INT32, &stream_idx, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u->dbus_conn), signal_msg, NULL)); - dbus_message_unref(signal_msg); -} -#endif - -static int init_ipc (struct userdata *u) { - int pre_mask; -#ifdef HAVE_DBUS -#ifndef USE_DBUS_PROTOCOL - DBusError err; - pa_dbus_connection *conn = NULL; - static const DBusObjectPathVTable vtable = { - .message_function = method_handler_for_vt, - }; -#endif -#endif - pa_assert(u); - - pa_log_info("Initialization for IPC"); - - pre_mask = umask(0); - if (mknod(KEYTONE_PATH,S_IFIFO|0660,0)<0) - pa_log_warn("mknod failed. errno=[%d][%s]", errno, strerror(errno)); - - umask(pre_mask); - - u->fd = open(KEYTONE_PATH, O_RDWR); - if (u->fd == -1) { - pa_log_warn("Check ipc node %s\n", KEYTONE_PATH); - goto fail; - } - - /* for non-blocking read */ - fcntl(u->fd, F_SETFL, O_NONBLOCK); - - /* change access mode so group can use keytone pipe */ - if (fchmod (u->fd, 0666) == -1) - pa_log_warn("Changing keytone access mode is failed. errno=[%d][%s]", errno, strerror(errno)); - - /* change group due to security request */ - if (fchown (u->fd, -1, KEYTONE_GROUP) == -1) - pa_log_warn("Changing keytone group is failed. errno=[%d][%s]", errno, strerror(errno)); - - u->io = u->module->core->mainloop->io_new(u->module->core->mainloop, u->fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP, io_event_callback, u); - -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - u->dbus_protocol = pa_dbus_protocol_get(u->module->core); - pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, SOUND_PLAYER_OBJECT_PATH, &sound_player_interface_info, u) >= 0); - pa_assert_se(pa_dbus_protocol_register_extension(u->dbus_protocol, SOUND_PLAYER_INTERFACE) >= 0); -#else - dbus_error_init(&err); - - if (!(conn = pa_dbus_bus_get(u->module->core, DBUS_BUS_SYSTEM, &err)) || dbus_error_is_set(&err)) { - if (conn) { - pa_dbus_connection_unref(conn); - } - pa_log_error("Unable to contact D-Bus system bus: %s: %s", err.name, err.message); - goto fail; - } else - pa_log_notice("Got dbus connection"); - - u->dbus_conn = conn; - pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(conn), SOUND_PLAYER_OBJECT_PATH, &vtable, u)); -#endif -#else - pa_log_error("DBUS is not supported\n"); - goto fail; -#endif - - return 0; -fail: - return -1; -} - -static void deinit_ipc (struct userdata *u) { - - pa_assert(u); - - if (u->io) - u->module->core->mainloop->io_free(u->io); - - if (u->fd > -1) - close(u->fd); - -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - if (u->dbus_protocol) { - pa_assert_se(pa_dbus_protocol_unregister_extension(u->dbus_protocol, SOUND_PLAYER_INTERFACE) >= 0); - pa_assert_se(pa_dbus_protocol_remove_interface(u->dbus_protocol, SOUND_PLAYER_OBJECT_PATH, sound_player_interface_info.name) >= 0); - pa_dbus_protocol_unref(u->dbus_protocol); - u->dbus_protocol = NULL; - } -#else - if (u->dbus_conn) { - if(!dbus_connection_unregister_object_path(pa_dbus_connection_get(u->dbus_conn), SOUND_PLAYER_OBJECT_PATH)) - pa_log_error("Failed to unregister object path"); - u->dbus_conn = NULL; - } -#endif -#endif -} - -static void io_event_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) { - struct userdata *u = userdata; - struct ipc_data data; - int ret = 0; - int data_size = 0; - int read_sum = 0; - int retry_count = 0; - - pa_assert(io); - pa_assert(u); - - if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { - pa_log_warn("Lost connection to client side"); - goto fail; - } - - if (events & PA_IO_EVENT_INPUT) { - data_size = sizeof(data); - memset(&data, 0, data_size); - while (read_sum != data_size && retry_count < RETRY_NUM) { - ret = read(fd, ((void *)&data)+read_sum, data_size-read_sum); - if (ret < 0 && errno == EAGAIN) - retry_count++; - else - read_sum += ret; - } - if (read_sum == data_size) { - pa_log_info("name(%s), role(%s), volume_gain_type(%s)", data.filename, data.role, data.volume_gain_type); - _simple_play(u, data.filename, data.role, data.volume_gain_type); - } else { - pa_log_warn("Fail to read, retry_count(%d), read sum(%d), err(%s)", retry_count, read_sum, pa_cstrerror(errno)); - } - } - - return; - -fail: - u->module->core->mainloop->io_free(u->io); - u->io = NULL; - - pa_module_unload_request(u->module, TRUE); -} - -static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, struct userdata *u) { - int32_t *stream_idx = NULL; - uint32_t idx = 0; - pa_core_assert_ref(core); - pa_sink_input_assert_ref(i); - - pa_log_info("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index); - -#ifdef HAVE_DBUS - PA_IDXSET_FOREACH(stream_idx, u->stream_idxs, idx) { - if (*stream_idx == (int32_t)(i->index)) { -#ifndef USE_DBUS_PROTOCOL - /* Send EOS signal for this stream */ - send_signal_for_eos(u, *stream_idx); -#endif - pa_idxset_remove_by_data(u->stream_idxs, stream_idx, NULL); - pa_xfree(stream_idx); - } - } -#endif - - return PA_HOOK_OK; -} - -int pa__init(pa_module *m) { - struct userdata *u; - - pa_assert(m); - - m->userdata = u = pa_xnew0(struct userdata, 1); - u->module = m; - u->io = NULL; - u->fd = -1; -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - u->dbus_protocol = NULL; -#else - u->dbus_conn = NULL; -#endif - u->stream_idxs = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); -#endif - if (init_ipc(u)) - goto fail; - - u->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_unlink_cb, u); - - return 0; - -fail: - pa__done(m); - return -1; -} - -void pa__done(pa_module *m) { - struct userdata *u; - pa_assert(m); - - if (!(u = m->userdata)) - return; - - if (u->sink_input_unlink_slot) - pa_hook_slot_free(u->sink_input_unlink_slot); - -#ifdef HAVE_DBUS - if (u->stream_idxs) - pa_idxset_free(u->stream_idxs, NULL); -#endif - - deinit_ipc(u); - - pa_xfree(u); -} diff --git a/src/modules/tizen/communicator.c b/src/modules/tizen/communicator.c deleted file mode 100644 index 1a06abc..0000000 --- a/src/modules/tizen/communicator.c +++ /dev/null @@ -1,90 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2015 Sangchul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "communicator.h" -#include - -struct _pa_communicator { - PA_REFCNT_DECLARE; - - pa_core *core; - pa_hook hooks[PA_COMMUNICATOR_HOOK_MAX]; -}; - -pa_communicator* pa_communicator_get(pa_core *core) { - pa_communicator *c; - unsigned i; - - pa_assert(core); - - if ((c = pa_shared_get(core, "communicator"))) - return pa_communicator_ref(c); - - c = pa_xnew0(pa_communicator, 1); - PA_REFCNT_INIT(c); - c->core = core; - - for (i = 0; i < PA_COMMUNICATOR_HOOK_MAX; i++) - pa_hook_init(&c->hooks[i], c); - - pa_shared_set(core, "communicator", c); - - return c; -} - -pa_communicator* pa_communicator_ref(pa_communicator *c) { - pa_assert(c); - pa_assert(PA_REFCNT_VALUE(c) > 0); - - PA_REFCNT_INC(c); - - return c; -} - -void pa_communicator_unref(pa_communicator *c) { - unsigned i; - - pa_assert(c); - pa_assert(PA_REFCNT_VALUE(c) > 0); - - if (PA_REFCNT_DEC(c) > 0) - return; - - for (i = 0; i < PA_COMMUNICATOR_HOOK_MAX; i++) - pa_hook_done(&c->hooks[i]); - - if (c->core) - pa_shared_remove(c->core, "communicator"); - - pa_xfree(c); -} - -pa_hook* pa_communicator_hook(pa_communicator *c, pa_communicator_hook_t hook) { - pa_assert(c); - pa_assert(PA_REFCNT_VALUE(c) > 0); - - return &c->hooks[hook]; -} - diff --git a/src/modules/tizen/communicator.h b/src/modules/tizen/communicator.h deleted file mode 100644 index 790652d..0000000 --- a/src/modules/tizen/communicator.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef foocommunicatorfoo -#define foocommunicatorfoo -#include - -typedef enum pa_communicator_hook { - PA_COMMUNICATOR_HOOK_SELECT_INIT_SINK_OR_SOURCE, - PA_COMMUNICATOR_HOOK_CHANGE_ROUTE, - PA_COMMUNICATOR_HOOK_UPDATE_ROUTE_OPTION, - PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED, - PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED, - PA_COMMUNICATOR_HOOK_MAX -} pa_communicator_hook_t; - -typedef struct _pa_communicator pa_communicator; - -pa_communicator* pa_communicator_get(pa_core *c); -pa_communicator* pa_communicator_ref(pa_communicator *c); -void pa_communicator_unref(pa_communicator *c); -pa_hook* pa_communicator_hook(pa_communicator *c, pa_communicator_hook_t hook); - -#endif diff --git a/src/modules/tizen/device-manager.c b/src/modules/tizen/device-manager.c deleted file mode 100644 index 361b2ea..0000000 --- a/src/modules/tizen/device-manager.c +++ /dev/null @@ -1,4277 +0,0 @@ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#ifdef HAVE_DBUS -#include -#include -#include -#endif - -#include "communicator.h" -#include "device-manager.h" - -#define DEVICE_MAP_FILE "/etc/pulse/device-map.json" -#define DEVICE_PROFILE_MAX 2 -#define DEVICE_STR_MAX 30 -#define DEVICE_DIRECTION_MAX 3 -#define DEVICE_PARAM_STRING_MAX 50 -#define DEVICE_AVAIL_COND_NUM_MAX 2 -#define DEVICE_AVAIL_COND_STR_MAX 6 -#define DEVICE_FILE_PER_TYPE_MAX 4 -#define DEVICE_FILE_STRING_MAX 4 - -#define DEVICE_TYPE_OBJECT "device-types" -#define DEVICE_FILE_OBJECT "device-files" -#define DEVICE_TYPE_PROP_DEVICE_TYPE "device-type" -#define DEVICE_TYPE_PROP_BUILTIN "builtin" -#define DEVICE_TYPE_PROP_DIRECTION "direction" -#define DEVICE_TYPE_PROP_AVAIL_CONDITION "avail-conditioin" -#define DEVICE_TYPE_PROP_PLAYBACK_DEVICES "playback-devices" -#define DEVICE_TYPE_PROP_CAPTURE_DEVICES "capture-devices" -#define DEVICE_TYPE_PROP_DEVICE_STRING "device-string" -#define DEVICE_TYPE_PROP_DEFAULT_PARAMS "default-params" -#define DEVICE_TYPE_PROP_ROLE "role" - -#define DEVICE_TYPE_STR_MAX 20 - -#define DEVICE_DIRECTION_STR_NONE "none" -#define DEVICE_DIRECTION_STR_OUT "out" -#define DEVICE_DIRECTION_STR_IN "in" -#define DEVICE_DIRECTION_STR_BOTH "both" - -#define DEVICE_AVAIL_CONDITION_STR_PULSE "pulse" -#define DEVICE_AVAIL_CONDITION_STR_DBUS "dbus" - -/* Properties of sink/sources */ -#define DEVICE_API_BLUEZ "bluez" -#define DEVICE_API_ALSA "alsa" -#define DEVICE_API_NULL "null" -#define DEVICE_BUS_USB "usb" -#define DEVICE_CLASS_SOUND "sound" -#define DEVICE_CLASS_MONITOR "monitor" - -/* Dbus defines */ -#define DBUS_INTERFACE_DEVICE_MANAGER "org.pulseaudio.DeviceManager" -#define DBUS_OBJECT_DEVICE_MANAGER "/org/pulseaudio/DeviceManager" - -#define DBUS_INTERFACE_DEVICED_SYSNOTI "org.tizen.system.deviced.SysNoti" -#define DBUS_OBJECT_DEVICED_SYSNOTI "/Org/Tizen/System/DeviceD/SysNoti" - -#define DBUS_INTERFACE_SOUND_SERVER "org.tizen.SoundServer1" -#define DBUS_OBJECT_SOUND_SERVER "/org/tizen/SoundServer1" - -#define DBUS_SERVICE_BLUEZ "org.bluez" -#define DBUS_INTERFACE_BLUEZ_HEADSET "org.bluez.Headset" -#define DBUS_INTERFACE_BLUEZ_DEVICE "org.bluez.Device1" -#define DBUS_OBJECT_BLUEZ "/org/bluez" - -#define DBUS_INTERFACE_MIRRORING_SERVER "org.tizen.scmirroring.server" -#define DBUS_OBJECT_MIRRORING_SERVER "/org/tizen/scmirroring/server" - -#define DBUS_SERVICE_HFP_AGENT "org.bluez.ag_agent" -#define DBUS_OBJECT_HFP_AGENT "/org/bluez/hfp_agent" -#define DBUS_INTERFACE_HFP_AGENT "Org.Hfp.App.Interface" - -#define DEVICE_MANAGER_INTROSPECT_XML \ - DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ - "\n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " " \ - " " \ - " " \ - " " \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - "\n" - - -#define FILTER_DEVICED_SYSNOTI \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_DEVICED_SYSNOTI "'" - -#define FILTER_SOUND_SERVER \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_SOUND_SERVER "'" - -#define FILTER_MIRRORING \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_MIRRORING_SERVER "', member='miracast_wfd_source_status_changed'" - -#define FILTER_BLUEZ \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_BLUEZ_HEADSET "', member='PropertyChanged'" - -static const char* const valid_alsa_device_modargs[] = { - "name", - "sink_name", - "sink_properties", - "source_name", - "source_properties", - "namereg_fail", - "device", - "device_id", - "format", - "rate", - "alternate_rate", - "channels", - "channel_map", - "fragments", - "fragment_size", - "mmap", - "tsched", - "tsched_buffer_size", - "tsched_buffer_watermark", - "ignore_dB", - "control", - "rewind_safeguard", - "deferred_volume", - "deferred_volume_safety_margin", - "deferred_volume_extra_delay", - "fixed_latency_range", - "need_audio_pm", - "start_threshold", - NULL -}; - - - -/* A macro to ease iteration through all entries */ -#define PA_HASHMAP_FOREACH_KEY(e, h, state, key) \ - for ((state) = NULL, (e) = pa_hashmap_iterate((h), &(state),(const void**)&(key)); (e); (e) = pa_hashmap_iterate((h), &(state), (const void**)&(key))) - -#define PA_DEVICE(pulse_device, pdt) \ - pdt == PA_DEVICE_TYPE_SINK ? ((pa_sink *) pulse_device) : ((pa_source *) pulse_device) - -#define PA_DEVICES(core, pdt) \ - pdt == PA_DEVICE_TYPE_SINK ? (((pa_core *) core)->sinks) : (((pa_core *) core)->sources) - -#define MAKE_SINK(s) ((pa_sink*) (s)) -#define MAKE_SOURCE(s) ((pa_source*) (s)) - -#define COMPOUND_STATE(d) (((dm_device_profile*)d)->playback_state | ((dm_device_profile*)d)->capture_state) - -#define BT_CVSD_CODEC_ID 1 // narrow-band -#define BT_MSBC_CODEC_ID 2 // wide-band -/* - Enums for represent values which is defined on other module. - This is needed to identify values which are sent by dbus or vconf. -*/ -typedef enum external_value_earjack_type { - EARJACK_DISCONNECTED = 0, - EARJACK_TYPE_SPK_ONLY = 1, - EARJACK_TYPE_SPK_WITH_MIC = 3, -} external_value_earjack_t; - -typedef enum external_value_bt_sco_type { - BT_SCO_DISCONNECTED = 0, - BT_SCO_CONNECTED = 1, -} external_value_bt_sco_t; - -typedef enum external_value_forwarding_type { - FORWARDING_DISCONNECTED = 0, - FORWARDING_CONNECTED = 1, -} external_value_mirroring_t; - -typedef enum external_value_hdmi_type { - HDMI_AUDIO_DISCONNECTED = -1, - HDMI_AUDIO_NOT_AVAILABLE = 0, - HDMI_AUDIO_AVAILABLE = 1, -} external_value_hdmi_t; - - -/* - Enums for represent device detected status (through dbus) - When some device is detected, one of these values should be saved in device_status hashmap. - device_detected_type_t is needed to distinguish detected device-types ( ex. earjack which can be out or both way) - So If you just want to know whether detected or not, can device_detected_t as mask. -*/ -typedef enum device_detected { - DEVICE_NOT_DETECTED = 0x00, - DEVICE_DETECTED = 0x01, -} device_detected_t; - -typedef enum device_detected_type { - DEVICE_DETECTED_BT_SCO = DEVICE_DETECTED, - DEVICE_DETECTED_FORWARDING = DEVICE_DETECTED, - DEVICE_DETECTED_HDMI = DEVICE_DETECTED, - DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC = DEVICE_DETECTED | 0x2, - DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC = DEVICE_DETECTED | 0x4, -} device_detected_type_t; - -typedef enum dm_device_class_type { - DM_DEVICE_CLASS_NONE, - DM_DEVICE_CLASS_ALSA, - DM_DEVICE_CLASS_TIZEN, - DM_DEVICE_CLASS_BT, - DM_DEVICE_CLASS_NULL, - DM_DEVICE_CLASS_MAX, -} dm_device_class_t; - - -typedef enum { - DEVICE_IO_DIRECTION_IN_FLAG = 0x0001, /**< Flag for input devices */ - DEVICE_IO_DIRECTION_OUT_FLAG = 0x0002, /**< Flag for output devices */ - DEVICE_IO_DIRECTION_BOTH_FLAG = 0x0004, /**< Flag for input/output devices (both directions are available) */ - DEVICE_TYPE_INTERNAL_FLAG = 0x0010, /**< Flag for built-in devices */ - DEVICE_TYPE_EXTERNAL_FLAG = 0x0020, /**< Flag for external devices */ - DEVICE_STATE_DEACTIVATED_FLAG = 0x1000, /**< Flag for deactivated devices */ - DEVICE_STATE_ACTIVATED_FLAG = 0x2000, /**< Flag for activated devices */ - DEVICE_ALL_FLAG = 0xFFFF, /**< Flag for all devices */ -} device_flag_t; - -typedef enum { - DEVICE_IO_DIRECTION_FLAGS = 0x000F, /**< Flag for io direction */ - DEVICE_TYPE_FLAGS = 0x00F0, /**< Flag for device type */ - DEVICE_STATE_FLAGS = 0xF000, /**< Flag for device state */ -} device_flags_type_t; - - -/************* structures for represent device items can be connected/disconnected */ -/* - Before beginning, There are two structure(dm_device, dm_device_profile) - for represent device by following reasons. - When bt-a2dp and bt-sco are on physically same device ,it is of course same device. - So those physically same device item are represended by dm_device, - and each profile is represented by dm_device_profile. -*/ - - -/* - Structure to represent physicall device. - This is profile known data-structure, which means it can have multiple profiles ( ex. bt-a2dp and sco) -*/ -struct dm_device { - uint32_t id; - char *type; - char *name; - const char *identifier; - - /* Indicate currently activated profile */ - uint32_t active_profile; - /* include profile_items(dm_device_profile) , currently has only one item except bt case*/ - pa_idxset *profiles; - - pa_device_manager *dm; -}; - -/* - Structure to represent each device profile (subtype). - Even if both-way device(earjack, sco..) , one device_profile. -*/ -typedef struct dm_device_profile { - char *profile; - dm_device_direction_t direction; - dm_device_state_t playback_state; - dm_device_state_t capture_state; - - /* Can get proper sink/source in hashmaps with key(=device_role) */ - pa_hashmap *playback_devices; - pa_hashmap *capture_devices; - - /* device belongs to */ - dm_device *device_item; -} dm_device_profile; - -/* - Structure to save parsed information about device-file. -*/ -struct device_file_map { - /* { key:device_string -> value:device_file_prop } */ - pa_idxset *playback; - pa_idxset *capture; -}; - -struct pa_device_manager { - pa_core *core; - pa_hook_slot *sink_put_hook_slot, *sink_unlink_hook_slot; - pa_hook_slot *source_put_hook_slot, *source_unlink_hook_slot; - pa_communicator *comm; - - /* - Idxset for save parsed information about device-type. - { device_type_info } - */ - pa_idxset *type_infos; - /* For save Parsed information about device-file */ - struct device_file_map *file_map; - - /* device list */ - pa_idxset *device_list; - /* - Hashmap for save statuses got through dbus. - { key:device_type -> value:(audio_detected_type_t or device_detected_t) } - */ - pa_idxset *device_status; - pa_dbus_connection *dbus_conn; -}; - -/***************** structures for static information get from json *********/ - -/* - Structure for informations related to some device-file(ex. 0:0) -*/ -struct device_file_info { - /* - String for identify target device. - ex) alsa:0,0 or null .. - */ - const char *device_string; - /* - For save roles which are supported on device file, and parameters. - { key:device_role -> value:parameters for load sink/source } - ex) "normal"->"rate=44100 tsched=0", "uhqa"->"rate=192000 mmap=1" - */ - pa_hashmap *roles; - /* - For save device-types related to device file. - { key:device_type-> value:pulse_device_prop } - */ - pa_hashmap *device_types; -}; - -/* structure for represent device-types(ex. builtin-speaker) properties*/ -struct device_type_info { - const char *type; - const char *profile; - pa_bool_t builtin; - /* - Possible directions of this device. - ex) speaker is always out, but earjack can be both or out. - */ - dm_device_direction_t direction[DEVICE_DIRECTION_MAX]; - /* - Conditions for make device available. - ex) Speaker be available, only if proper pcm-device exists. - but audio-jack is available, if pcm-device exists and got detected status. - */ - char avail_condition[DEVICE_AVAIL_COND_NUM_MAX][DEVICE_AVAIL_COND_STR_MAX]; - int num; - /* - For save supported roles and related device-file. - { key:role -> value:device_string ] - */ - pa_hashmap *playback_devices; - pa_hashmap *capture_devices; -}; - -struct device_status_info { - const char *type; - const char *profile; - /* Identify devices among same device-types (for multi-device), currently not works*/ - const char *identifier; - device_detected_t detected; - device_detected_type_t detected_type; -}; - -struct pulse_device_prop { - /* roles related to (device_type + device_file)*/ - pa_idxset *roles; - /* For save that this devie_type is activated or not on sink/source */ - int status; -}; -/******************************************************************************/ - -int device_id_max_g = 1; - -#ifdef HAVE_DBUS - -/*** Defines for method handle ***/ -/* method handlers */ -static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata); - -static void notify_device_connection_changed(dm_device *device_item, pa_bool_t connected, pa_device_manager *dm); -static void notify_device_info_changed(dm_device *device_item, dm_device_changed_info_t changed_type, pa_device_manager *dm); - -static int method_call_bt_sco(DBusConnection *conn, pa_bool_t onoff); -static int method_call_bt_sco_get_property(DBusConnection *conn, pa_bool_t *is_wide_band, pa_bool_t *nrec); -static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name); - -enum method_handler_index { - METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST, - METHOD_HANDLER_GET_BT_A2DP_STATUS, - METHOD_HANDLER_LOAD_SINK, - METHOD_HANDLER_STATUS_TEST, - METHOD_HANDLER_MAX -}; - -static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { - [METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST] = { - .method_name = "GetConnectedDeviceList", - .receive_cb = handle_get_connected_device_list }, - [METHOD_HANDLER_GET_BT_A2DP_STATUS] = { - .method_name = "GetBTA2DPStatus", - .receive_cb = handle_get_bt_a2dp_status }, - [METHOD_HANDLER_LOAD_SINK] = { - .method_name = "LoadSink", - .receive_cb = handle_load_sink}, - [METHOD_HANDLER_STATUS_TEST] = { - .method_name = "TestStatusChange", - .receive_cb = handle_test_device_status_change}, -}; - -/*** Defines for signal send ***/ - -enum signal_index { - SIGNAL_DEVICE_CONNECTED, - SIGNAL_DEVICE_INFO_CHANGED, - SIGNAL_MAX -}; - -#endif - -static pa_bool_t device_type_is_valid(const char *device_type) { - if (!device_type) - return FALSE; - else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) - return TRUE; - else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) - return TRUE; - else if (pa_streq(device_type, DEVICE_TYPE_MIC)) - return TRUE; - else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) - return TRUE; - else if (pa_streq(device_type, DEVICE_TYPE_BT)) - return TRUE; - else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) - return TRUE; - else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) - return TRUE; - else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) - return TRUE; - else - return FALSE; -} - -static const char* device_direction_to_string(dm_device_direction_t direction) { - if (direction <= DM_DEVICE_DIRECTION_NONE || direction > DM_DEVICE_DIRECTION_BOTH) { - return NULL; - } - - if (direction == DM_DEVICE_DIRECTION_NONE) - return DEVICE_DIRECTION_STR_NONE; - else if (direction == DM_DEVICE_DIRECTION_OUT) - return DEVICE_DIRECTION_STR_OUT; - else if (direction == DM_DEVICE_DIRECTION_IN) - return DEVICE_DIRECTION_STR_IN; - else if (direction == DM_DEVICE_DIRECTION_BOTH) - return DEVICE_DIRECTION_STR_BOTH; - else - return NULL; -} - -static pa_bool_t device_role_is_valid(const char *device_role) { - if (!device_role) - return FALSE; - else if (pa_streq(device_role, DEVICE_ROLE_NORMAL)) - return TRUE; - else if (pa_streq(device_role, DEVICE_ROLE_VOIP)) - return TRUE; - else if (pa_streq(device_role, DEVICE_ROLE_LOW_LATENCY)) - return TRUE; - else if (pa_streq(device_role, DEVICE_ROLE_HIGH_LATENCY)) - return TRUE; - else if (pa_streq(device_role, DEVICE_ROLE_UHQA)) - return TRUE; - else - return FALSE; -} - -static dm_device_direction_t device_direction_to_int(const char *device_direction) { - if (!device_direction) { - return -1; - } - - if (pa_streq(device_direction, DEVICE_DIRECTION_STR_NONE)) { - return DM_DEVICE_DIRECTION_NONE; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_OUT)) { - return DM_DEVICE_DIRECTION_OUT; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_IN)) { - return DM_DEVICE_DIRECTION_IN; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_BOTH)) { - return DM_DEVICE_DIRECTION_BOTH; - } else { - return -1; - } -} - -static void type_info_free_func(struct device_type_info *type_info) { - if (!type_info) - return; - - if (type_info->playback_devices) - pa_hashmap_free(type_info->playback_devices); - if (type_info->capture_devices) - pa_hashmap_free(type_info->capture_devices); - -} - -static void file_info_free_func(struct device_file_info *file_info) { - if (!file_info) - return; - - if (file_info->roles) - pa_hashmap_free(file_info->roles); -} - -static void profile_item_free_func(dm_device_profile *profile_item) { - if (!profile_item) - return; - - if (profile_item->profile) { - pa_xfree(profile_item->profile); - } - - if (profile_item->playback_devices) { - pa_hashmap_free(profile_item->playback_devices); - } - if (profile_item->capture_devices) { - pa_hashmap_free(profile_item->capture_devices); - } - - profile_item->device_item = NULL; - - pa_xfree(profile_item); -} - -static void device_item_free_func(dm_device *device_item) { - if (!device_item) - return; - - if (device_item->type) - pa_xfree(device_item->type); - if (device_item->name) - pa_xfree(device_item->name); - if (device_item->profiles) - pa_idxset_free(device_item->profiles, (pa_free_cb_t)profile_item_free_func); - - pa_xfree(device_item); -} - -static pa_proplist* pulse_device_get_proplist(void *pulse_device, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return MAKE_SINK(pulse_device)->proplist; - else - return MAKE_SOURCE(pulse_device)->proplist; -} - -static pa_core* pulse_device_get_core(void *pulse_device, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return MAKE_SINK(pulse_device)->core; - else - return MAKE_SOURCE(pulse_device)->core; -} - -static char* pulse_device_get_name(void *pulse_device, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return MAKE_SINK(pulse_device)->name; - else - return MAKE_SOURCE(pulse_device)->name; -} - -static pa_idxset* pulse_core_get_device_list(pa_core *core, pa_device_type_t pdt) { - if (pdt == PA_DEVICE_TYPE_SINK) - return core->sinks; - else - return core->sources; -} - -static pa_bool_t pulse_device_is_alsa(pa_proplist *prop) { - const char *api_name = NULL; - - if (!prop) { - return FALSE; - } - - if ((api_name = pa_proplist_gets(prop, PA_PROP_DEVICE_API))) { - if (pa_streq (api_name, DEVICE_API_ALSA)) { - return TRUE; - } else { - return FALSE; - } - } else { - return FALSE; - } -} - - -static pa_bool_t pulse_device_is_bluez(pa_proplist *prop) { - const char *api_name = NULL; - - if (!prop) { - return FALSE; - } - - if ((api_name = pa_proplist_gets(prop, PA_PROP_DEVICE_API))) { - if (pa_streq (api_name, DEVICE_API_BLUEZ)) { - return TRUE; - } else { - return FALSE; - } - } else { - return FALSE; - } -} - -static pa_bool_t pulse_device_is_tizenaudio(void *pulse_device, pa_device_type_t pdt) { - pa_sink *sink; - - if (!pulse_device) { - return FALSE; - } - - if (pdt == PA_DEVICE_TYPE_SOURCE) { - return FALSE; - } - - sink = (pa_sink *) pulse_device; - return pa_streq(sink->module->name, "module-tizenaudio-sink"); -} - -static pa_bool_t pulse_device_is_usb(pa_proplist *prop) { - const char *bus_name = NULL; - - if ((bus_name = pa_proplist_gets(prop, PA_PROP_DEVICE_BUS))) { - if (pa_streq (bus_name, DEVICE_BUS_USB)) { - return TRUE; - } else { - return FALSE; - } - } else { - pa_log_debug("This device doesn't have property '%s'", PA_PROP_DEVICE_BUS); - return FALSE; - } -} - -static pa_bool_t pulse_device_is_null(void *pulse_device, pa_device_type_t pdt) { - pa_sink *sink; - pa_source *source; - - if (!pulse_device) - return FALSE; - - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - return pa_streq(sink->module->name, "module-null-sink"); - } else { - source = (pa_source *) pulse_device; - - return pa_streq(source->module->name, "module-null-source"); - } -} - -static const char* device_class_to_string(dm_device_class_t device_class) { - if (device_class == DM_DEVICE_CLASS_ALSA) { - return "alsa"; - } else if (device_class == DM_DEVICE_CLASS_TIZEN) { - return "tizen"; - } else if (device_class == DM_DEVICE_CLASS_BT) { - return "bt"; - } else if (device_class == DM_DEVICE_CLASS_NULL) { - return "null"; - } else if (device_class == DM_DEVICE_CLASS_NONE) { - return "none"; - } else { - return NULL; - } -} - -static dm_device_class_t device_string_get_class(const char *device_string) { - if (!device_string) { - return DM_DEVICE_CLASS_NONE; - } - - if (device_string == strstr(device_string, "alsa")) { - return DM_DEVICE_CLASS_ALSA; - } else if (device_string == strstr(device_string, "null")) { - return DM_DEVICE_CLASS_NULL; - } else if (device_string == strstr(device_string, "tizen")) { - return DM_DEVICE_CLASS_TIZEN; - } else { - return DM_DEVICE_CLASS_NONE; - } -} - -static const char* device_string_get_value(const char *device_string) { - int len; - const char *end_p, *value_p; - - if (!device_string) { - return NULL; - } - - len = strlen(device_string); - end_p = device_string + len -1; - - if (!(value_p = strchr(device_string, ':'))) { - return NULL; - } - if (value_p < end_p) { - return value_p + 1; - } else { - return NULL; - } -} - -static dm_device_class_t pulse_device_get_class(void *pulse_device, pa_device_type_t pdt) { - pa_sink *sink = NULL; - pa_source *source = NULL; - - if (!pulse_device) { - pa_log_error("pulse_device null"); - return DM_DEVICE_CLASS_NONE; - } - - if (pdt == PA_DEVICE_TYPE_SINK) - sink = (pa_sink *) pulse_device; - else - source = (pa_source *) pulse_device; - - if (pulse_device_is_null(pulse_device, pdt)) { - return DM_DEVICE_CLASS_NULL; - } else if (pulse_device_is_alsa(pdt == PA_DEVICE_TYPE_SINK ? sink->proplist : source->proplist)) { - return DM_DEVICE_CLASS_ALSA; - } else if (pulse_device_is_tizenaudio(pulse_device, pdt)) { - return DM_DEVICE_CLASS_TIZEN; - } else if (pulse_device_is_bluez(pdt == PA_DEVICE_TYPE_SINK ? sink->proplist : source->proplist)) { - return DM_DEVICE_CLASS_BT; - } else { - return DM_DEVICE_CLASS_NONE; - } -} - -static const char* device_class_get_module_name(dm_device_class_t device_class, pa_device_type_t pdt) { - if (device_class == DM_DEVICE_CLASS_NONE) { - return NULL; - } else if (device_class == DM_DEVICE_CLASS_ALSA) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-alsa-sink" : "module-alsa-source"; - } else if (device_class == DM_DEVICE_CLASS_TIZEN) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-tizenaudio-sink" : NULL; - } else if (device_class == DM_DEVICE_CLASS_BT) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-bluez5-device" : NULL; - } else if (device_class == DM_DEVICE_CLASS_NULL) { - return pdt == PA_DEVICE_TYPE_SINK ? "module-null-sink" : "module-null-source"; - } else { - return NULL; - } -} - -static int compare_device_profile(const char *device_profile1, const char *device_profile2) { - if (!device_profile1 && !device_profile2) { - return 0; - } else if (!device_profile1 || !device_profile2) { - return 1; - } else if (pa_streq(device_profile1, device_profile2)) { - return 0; - } else { - return 1; - } -} - -static int compare_device_type(const char *device_type1, const char *device_profile1, const char *device_type2, const char *device_profile2) { - if (!device_type1 || !device_type2) { - return -1; - } - if (pa_streq(device_type1, device_type2)) { - return compare_device_profile(device_profile1, device_profile2); - } - return 1; -} - -static struct device_type_info* _device_manager_get_type_info(pa_idxset *type_infos, const char *device_type, const char *device_profile) { - struct device_type_info *type_info; - uint32_t type_idx; - - PA_IDXSET_FOREACH(type_info, type_infos, type_idx) { - if (!compare_device_type(type_info->type, type_info->profile, device_type, device_profile)) { - return type_info; - } - } - - return NULL; -} - -static struct device_status_info* _device_manager_get_status_info(pa_idxset *status_infos, const char *device_type, const char *device_profile, const char *identifier) { - struct device_status_info *status_info; - uint32_t status_idx; - - PA_IDXSET_FOREACH(status_info, status_infos, status_idx) { - if (!compare_device_type(status_info->type, status_info->profile, device_type, device_profile)) { - if (!status_info->identifier && !identifier) { - return status_info; - } else if (!status_info->identifier || !identifier) { - continue; - } else if (pa_streq(status_info->identifier, identifier)) { - return status_info; - } else { - continue; - } - } - } - - return NULL; -} - -static struct device_file_info* _device_manager_get_file_info(pa_idxset *file_infos, const char *device_string) { - struct device_file_info *file_info; - uint32_t file_idx; - if (!file_infos) - return NULL; - - PA_IDXSET_FOREACH(file_info, file_infos, file_idx) { - if (file_info->device_string) { - if (pa_streq(file_info->device_string, device_string)) { - return file_info; - } - } - } - - return NULL; -} - -static dm_device* _device_manager_get_device(pa_idxset *device_list, const char *device_type) { - dm_device *device_item; - uint32_t device_idx; - - if (!device_list || !device_type) - return NULL; - - PA_IDXSET_FOREACH(device_item, device_list, device_idx) { - if (pa_streq(device_item->type, device_type)) { - return device_item; - } - } - - return NULL; -} - -static dm_device* _device_manager_get_device_with_id(pa_idxset *device_list, uint32_t id) { - dm_device *device_item; - uint32_t idx; - - pa_assert(device_list); - - PA_IDXSET_FOREACH(device_item, device_list, idx) { - if (device_item->id == id) { - return device_item; - } - } - return NULL; -} - -static void dump_playback_device_list(pa_hashmap *playback_devices) { - pa_sink *sink = NULL; - void *state = NULL; - const char *role; - - if (!playback_devices) { - return ; - } - - pa_log_debug(" playback device list"); - if (pa_hashmap_size(playback_devices) == 0) { - pa_log_debug(" empty"); - return; - } - PA_HASHMAP_FOREACH_KEY(sink, playback_devices, state, role) { - pa_log_debug(" %-13s -> %s", role, sink->name); - } -} - -static void dump_capture_device_list(pa_hashmap *capture_devices) { - pa_source *source= NULL; - void *state = NULL; - const char *role; - - if (!capture_devices) { - return ; - } - - pa_log_debug(" capture device list"); - if (pa_hashmap_size(capture_devices) == 0) { - pa_log_debug(" empty"); - return; - } - PA_HASHMAP_FOREACH_KEY(source, capture_devices, state, role) { - pa_log_debug(" %-13s -> %s", role, source->name); - } -} - -static void dump_device_profile_info(dm_device_profile *profile_item) { - if (!profile_item) - return; - - pa_log_debug(" profile : %s", profile_item->profile); - pa_log_debug(" direction : %s", device_direction_to_string(profile_item->direction)); - pa_log_debug(" activated : %s", COMPOUND_STATE(profile_item) == DM_DEVICE_STATE_ACTIVATED ? "activated" : "not activated"); - dump_playback_device_list(profile_item->playback_devices); - dump_capture_device_list(profile_item->capture_devices); -} - -static void dump_device_info(dm_device *device_item) { - dm_device_profile *profile_item = NULL; - uint32_t device_idx = 0; - - if (!device_item) - return; - if (!device_item->profiles) { - pa_log_warn("empty device item"); - return; - } - - pa_log_debug(" id : %u", device_item->id); - pa_log_debug(" type : %s", device_item->type); - pa_log_debug(" name : %s", device_item->name); - pa_log_debug(" active-profile : %u", device_item->active_profile); - PA_IDXSET_FOREACH(profile_item, device_item->profiles, device_idx) { - pa_log_debug(" (Profile #%u)", device_idx); - dump_device_profile_info(profile_item); - } -} - -static void dump_device_list(pa_device_manager *dm) { - dm_device *device_item = NULL; - uint32_t device_idx = 0; - - if (!dm || !dm->device_list) { - return; - } - - pa_log_debug("====== Device List Dump ======"); - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - pa_log_debug("[ Device #%u ]", device_item->id); - dump_device_info(device_item); - } - pa_log_debug("==================================="); -} -static pa_bool_t pulse_device_class_is_sound(pa_proplist *prop) { - const char *device_class = NULL; - - if ((device_class = pa_proplist_gets(prop, PA_PROP_DEVICE_CLASS))) { - if (device_class && pa_streq (device_class, DEVICE_CLASS_SOUND)) { - return TRUE; - } else { - return FALSE; - } - } else { - return FALSE; - } -} - -static pa_bool_t pulse_device_class_is_monitor(pa_proplist *prop) { - const char *device_class = NULL; - - if (!prop) { - return FALSE; - } - - if ((device_class = pa_proplist_gets(prop, PA_PROP_DEVICE_CLASS))) { - if (device_class && pa_streq (device_class, DEVICE_CLASS_MONITOR)) { - return TRUE; - } else { - return FALSE; - } - } else { - return FALSE; - } -} -static void* pulse_device_get_opposite_sibling_device(void *pulse_device, pa_device_type_t pdt) { - const char *sysfs_path, *sysfs_path_tmp; - uint32_t device_idx; - void *pulse_device_tmp; - pa_core *core; - - pa_assert(pulse_device); - - if (!(sysfs_path = pa_proplist_gets(pulse_device_get_proplist(pulse_device, pdt), "sysfs.path"))) { - pa_log_warn("No sysfs.path for '%s'", pulse_device_get_name(pulse_device, pdt)); - return NULL; - } - - core = pulse_device_get_core(pulse_device, pdt); - - PA_IDXSET_FOREACH(pulse_device_tmp, pulse_core_get_device_list(core, !pdt), device_idx) { - if (!pulse_device_class_is_sound(pulse_device_get_proplist(pulse_device_tmp, !pdt))) - continue; - sysfs_path_tmp = pa_proplist_gets(pulse_device_get_proplist(pulse_device_tmp, !pdt), "sysfs.path"); - if (sysfs_path_tmp && pa_streq(sysfs_path_tmp, sysfs_path)) { - return pulse_device_tmp; - } - } - - return NULL; -} - -static int pulse_device_get_alsa_device_string(pa_proplist *prop, char **device_string) { - const char *device_string_prop = NULL; - char *device_string_tmp; - - if (!prop || !device_string) { - pa_log_error("Invalid Parameter"); - return -1; - } - - if (!(device_string_prop = pa_proplist_gets(prop, "device.string"))) { - pa_log_error("failed to get property 'device.string'"); - return -1; - } - if (!(device_string_tmp = strchr(device_string_prop, ':'))) { - pa_log_error("failed to parse device string"); - return -1; - } - - if (((device_string_tmp + 1) == '\0')) { - pa_log_error("no device string value"); - return -1; - } - - *device_string = device_string_tmp + 1; - - return 0; -} - -static const char* build_params_to_load_device(const char *device_string, const char *params, dm_device_class_t device_class) { - pa_strbuf *args_buf; - static char args[DEVICE_PARAM_STRING_MAX] = {0,}; - - if (!device_string) { - pa_log_error("device string null"); - return NULL; - } - - if (device_class == DM_DEVICE_CLASS_NULL) { - return params; - } else if (device_class == DM_DEVICE_CLASS_ALSA) { - const char *alsa_device_name; - if (!(alsa_device_name = device_string_get_value(device_string))) { - pa_log_error("Invalid device string for alsa-device, '%s'", device_string); - return NULL; - } - args_buf = pa_strbuf_new(); - pa_strbuf_printf(args_buf, "device=hw:%s ", alsa_device_name); - if (params) { - pa_strbuf_printf(args_buf, "%s", params); - } - strncpy(args, pa_strbuf_tostring_free(args_buf), DEVICE_PARAM_STRING_MAX); - } else { - return params; - } - - return (const char*) args; -} - -static const char* pulse_device_get_device_string_removed_argument(void *pulse_device, pa_device_type_t pdt) { - static char removed_param[DEVICE_PARAM_STRING_MAX] = {0,}; - char *device_string_p = NULL; - char *next_p = NULL; - const char *params_p, *params; - char *end_p = NULL; - int len = 0, prev_len = 0; - pa_sink *sink; - pa_source *source; - - if (pdt == PA_DEVICE_TYPE_SINK) - sink = (pa_sink *) pulse_device; - else - source = (pa_source *) pulse_device; - - params = pdt == PA_DEVICE_TYPE_SINK ? sink->module->argument : source->module->argument; - params_p = params; - - if (!params) { - return NULL; - } - if (!(device_string_p = strstr(params, "device="))) { - return params; - } - - next_p = device_string_p; - while (!isblank(*next_p)) { - next_p++; - } - while (isblank(*next_p)) { - next_p++; - } - - strncpy(removed_param, next_p, DEVICE_PARAM_STRING_MAX); - - if (device_string_p > params_p) { - prev_len = device_string_p - params_p; - len = strlen(removed_param); - end_p = removed_param + len; - *end_p = ' '; - end_p++; - strncpy(end_p, params_p, prev_len); - } - - return removed_param; -} - - -static int compare_device_params(const char *params1, const char *params2) { - const char *key = NULL; - const char *value1, *value2; - pa_modargs *modargs1, *modargs2; - void *state = NULL; - int ret = 0; - - if (!params1 && !params2) - return 0; - if (!params1 || !params2) - return -1; - - modargs1 = pa_modargs_new(params1, valid_alsa_device_modargs); - modargs2 = pa_modargs_new(params2, valid_alsa_device_modargs); - - if (!modargs1 || !modargs2) { - ret = 1; - goto end; - } - - for (state = NULL, key = pa_modargs_iterate(modargs1, &state); key; key = pa_modargs_iterate(modargs1, &state)) { - value1 = pa_modargs_get_value(modargs1, key, NULL); - value2 = pa_modargs_get_value(modargs2, key, NULL); - if (!value1 || !value2 || !pa_streq(value1, value2)) { - ret = 1; - goto end; - } - } - - for (state = NULL, key = pa_modargs_iterate(modargs2, &state); key; key = pa_modargs_iterate(modargs2, &state)) { - value1 = pa_modargs_get_value(modargs1, key, NULL); - value2 = pa_modargs_get_value(modargs2, key, NULL); - if (!value1 || !value2 || !pa_streq(value1, value2)) { - ret = 1; - goto end; - } - } - -end: - - if (modargs1) - pa_modargs_free(modargs1); - if (modargs2) - pa_modargs_free(modargs2); - - - return ret; -} - -static int compare_device_params_with_module_args(void *pulse_device, pa_device_type_t pdt, const char *params) { - const char *removed_module_args; - const char *module_args; - pa_sink *sink; - pa_source *source; - - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - module_args = sink->module->argument; - } else { - source = (pa_source *) pulse_device; - module_args = source->module->argument; - } - - if (!params && !module_args) - return 0; - if (!params || !module_args) - return -1; - - removed_module_args = pulse_device_get_device_string_removed_argument(pulse_device, pdt); - return compare_device_params(params, removed_module_args); -} - -static const char* pulse_device_get_device_string(void *pulse_device, pa_device_type_t pdt) { - dm_device_class_t device_class; - static char device_string[DEVICE_STR_MAX] = {0,}; - char *device_string_val = NULL; - pa_sink *sink; - pa_source *source; - - if (!pulse_device) { - pa_log_error("pulse_device null"); - return NULL; - } - - device_class = pulse_device_get_class(pulse_device, pdt); - - if (pdt == PA_DEVICE_TYPE_SINK) - sink = (pa_sink *) pulse_device; - else - source = (pa_source *) pulse_device; - - if (device_class == DM_DEVICE_CLASS_ALSA) { - if (pulse_device_get_alsa_device_string(pdt == PA_DEVICE_TYPE_SINK ? sink->proplist : source->proplist, &device_string_val) < 0) - return NULL; - snprintf(device_string, DEVICE_STR_MAX, "alsa:%s", device_string_val); - return device_string; - } else if (device_class == DM_DEVICE_CLASS_NULL) { - return "null"; - } else if (device_class == DM_DEVICE_CLASS_TIZEN) { - return "tizen"; - } else if (device_class == DM_DEVICE_CLASS_BT) { - return "bt"; - } else { - return device_string; - } -} - -/* pulse_device is sink or source */ -static pa_bool_t pulse_device_same_device_string(void *pulse_device, pa_device_type_t pdt, const char *device_string) { - const char *pulse_device_string; - - if (!pulse_device || !device_string) { - return FALSE; - } - - if (!(pulse_device_string = pulse_device_get_device_string(pulse_device, pdt))) { - return FALSE; - } - - return pa_streq(pulse_device_string, device_string); -} - -static dm_device* _device_item_set_active_profile(dm_device *device_item, const char *device_profile) { - dm_device_profile *profile_item = NULL; - uint32_t idx, active_profile_idx = PA_INVALID_INDEX, prev_active_profile = PA_INVALID_INDEX; - - if (!device_item || !device_item->profiles ) { - pa_log_error("Invalid Parameter"); - return NULL; - } - - prev_active_profile = device_item->active_profile; - PA_IDXSET_FOREACH(profile_item, device_item->profiles, idx) { - if (!compare_device_profile(profile_item->profile, device_profile)) { - active_profile_idx = idx; - } - } - - if (active_profile_idx != PA_INVALID_INDEX) { - device_item->active_profile = active_profile_idx; - } else { - return NULL; - } - - if (prev_active_profile != device_item->active_profile) { - pa_log_debug("%s's active profile : %u", device_item->name, device_item->active_profile); - notify_device_info_changed(device_item, DM_DEVICE_CHANGED_INFO_SUBTYPE, device_item->dm); - } - - return device_item; -} - -static int get_profile_priority(const char *device_profile) { - if (!device_profile) { - return 0; - } else if (pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) { - return 1; - } else if (pa_streq(device_profile, DEVICE_PROFILE_BT_A2DP)) { - return 2; - } else { - return -1; - } -} - -static int compare_profile_priority(const char *device_profile1, const char *device_profile2) { - int priority1, priority2; - - priority1 = get_profile_priority(device_profile1); - priority2 = get_profile_priority(device_profile2); - - if (priority1 > priority2) { - return 1; - } else if (priority1 == priority2) { - return 0; - } else { - return -1; - } -} - -static dm_device* _device_item_set_active_profile_auto(dm_device *device_item) { - dm_device_profile *profile_item = NULL, *prev_profile_item = NULL; - uint32_t idx, prev_active_profile; - unsigned int device_size; - - if (!device_item || !device_item->profiles ) { - pa_log_error("Invalid Parameter"); - return NULL; - } - - prev_active_profile = device_item->active_profile; - - device_size = pa_idxset_size(device_item->profiles); - if (device_size == 1) { - pa_idxset_first(device_item->profiles, &idx); - device_item->active_profile = idx; - } else if (device_size == 0) { - device_item->active_profile = PA_INVALID_INDEX; - return device_item; - } else { - PA_IDXSET_FOREACH(profile_item, device_item->profiles, idx) { - if (prev_profile_item) { - if (compare_profile_priority(profile_item->profile, prev_profile_item->profile) > 0) { - device_item->active_profile = idx; - } - } - prev_profile_item = profile_item; - } - } - - if (prev_active_profile != device_item->active_profile) { - pa_log_debug("%s's active profile : %u", device_item->name, device_item->active_profile); - notify_device_info_changed(device_item, DM_DEVICE_CHANGED_INFO_SUBTYPE, device_item->dm); - } - - return device_item; -} - -static dm_device* _device_item_add_profile(dm_device *device_item, dm_device_profile *profile_item, uint32_t *idx, pa_device_manager *dm) { - uint32_t profile_idx; - - pa_assert(device_item); - pa_assert(device_item->profiles); - pa_assert(profile_item); - pa_assert(dm); - - pa_idxset_put(device_item->profiles, profile_item, &profile_idx); - _device_item_set_active_profile_auto(device_item); - profile_item->device_item = device_item; - - return device_item; -} - - -static int _device_list_add_device(pa_idxset *device_list, dm_device *device_item, pa_device_manager *dm) { - pa_assert(device_list); - pa_assert(device_item); - - if (pa_idxset_put(device_list, device_item, NULL) < 0) - return -1; - - pa_log_debug("Notify Device connected"); - - return 0; -} - - -static int _device_list_remove_device(pa_idxset *device_list, dm_device *device_item, pa_device_manager *dm) { - pa_assert(device_list); - pa_assert(device_item); - - if (!pa_idxset_remove_by_data(device_list, device_item, NULL)) - return -1; - - return 0; -} - - - -static dm_device* create_device_item(const char *device_type, const char *name, dm_device_profile *profile_item, pa_device_manager *dm) { - dm_device *device_item = NULL; - - pa_assert(device_type); - pa_assert(profile_item); - - pa_log_debug("Create device item for %s", device_type); - - device_item = (dm_device *)pa_xmalloc(sizeof(dm_device)); - device_item->id = device_id_max_g++; - device_item->type = strdup(device_type); - device_item->active_profile = PA_INVALID_INDEX; - device_item->profiles = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - device_item->dm = dm; - - if (name) { - device_item->name = strdup(name); - } else { - device_item->name = strdup(device_type); - } - - _device_item_add_profile(device_item, profile_item, NULL, dm); - _device_list_add_device(dm->device_list, device_item, dm); - notify_device_connection_changed(device_item, TRUE, dm); - - return device_item; -} - -static void destroy_device_item(dm_device *device_item, pa_device_manager *dm) { - if (!device_item) { - return; - } - - pa_log_debug("Destroy device item which of type is %s", device_item->type); - - _device_list_remove_device(dm->device_list, device_item, dm); - - device_item_free_func(device_item); -} - -static unsigned _device_item_get_size(dm_device *device_item) { - unsigned int profile_num; - pa_assert(device_item); - - profile_num = pa_idxset_size(device_item->profiles); - return profile_num; -} - -static dm_device* _device_item_remove_profile(dm_device *device_item, dm_device_profile *profile_item, pa_device_manager *dm) { - unsigned int profile_num; - - pa_assert(device_item); - pa_assert(device_item->profiles); - pa_assert(profile_item); - pa_assert(dm); - - profile_num = pa_idxset_size(device_item->profiles); - - if (profile_num == 0) { - pa_log_error("Already Empty device_item"); - return NULL; - } - - pa_idxset_remove_by_data(device_item->profiles, profile_item, NULL); - _device_item_set_active_profile_auto(device_item); - - return device_item; -} - -static dm_device_profile* create_device_profile(const char *device_profile, dm_device_direction_t direction, pa_hashmap *playback, pa_hashmap *capture) { - dm_device_profile *profile_item = NULL; - - pa_assert(direction >= DM_DEVICE_DIRECTION_IN && direction <= DM_DEVICE_DIRECTION_BOTH); - - pa_log_debug("Create device profile for %s, direction:%s", device_profile, device_direction_to_string(direction)); - - if (!(profile_item = (dm_device_profile *)pa_xmalloc(sizeof(dm_device_profile)))) { - pa_log_error("Cannot alloc for device item"); - return NULL; - } - profile_item->profile = device_profile ? strdup(device_profile) : NULL; - profile_item->direction = direction; - profile_item->playback_state = DM_DEVICE_STATE_DEACTIVATED; - profile_item->capture_state = DM_DEVICE_STATE_DEACTIVATED; - profile_item->playback_devices = playback; - profile_item->capture_devices = capture; - - return profile_item; -} - -static dm_device* destroy_device_profile(dm_device_profile *profile_item, pa_device_manager *dm) { - dm_device *device_item; - - pa_assert(profile_item); - pa_assert(profile_item->device_item); - - device_item = profile_item->device_item; - - pa_log_debug("Destroy device profile item which of profile is %s", profile_item->profile); - - if (_device_item_get_size(device_item) == 1) { - destroy_device_item(device_item, dm); - return NULL; - } else { - _device_item_remove_profile(device_item, profile_item, dm); - profile_item_free_func(profile_item); - return device_item; - } -} - -static void _device_profile_update_direction(dm_device_profile *profile_item) { - int prev_direction; - pa_bool_t playback_exist = FALSE, capture_exist = FALSE; - - if (!profile_item) - return; - - prev_direction = profile_item->direction; - - if (profile_item->playback_devices) { - if (pa_hashmap_size(profile_item->playback_devices) > 0) { - playback_exist = TRUE; - } - } - if (profile_item->capture_devices) { - if (pa_hashmap_size(profile_item->capture_devices) > 0) { - capture_exist = TRUE; - } - } - - if (playback_exist && capture_exist) { - profile_item->direction = DM_DEVICE_DIRECTION_BOTH; - } else if (playback_exist) { - profile_item->direction = DM_DEVICE_DIRECTION_OUT; - } else if (capture_exist) { - profile_item->direction = DM_DEVICE_DIRECTION_IN; - } else { - profile_item->direction = DM_DEVICE_DIRECTION_NONE; - } - - pa_log_debug("direction updated '%s'->'%s'", device_direction_to_string(prev_direction), device_direction_to_string(profile_item->direction)); -} - -static dm_device_profile* _device_profile_add_pulse_device(dm_device_profile *profile_item, const char *role, void *pulse_device, pa_device_type_t pdt) { - if (!profile_item || !pulse_device || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - - if (pdt == PA_DEVICE_TYPE_SINK) { - if (!(profile_item->playback_devices)) - profile_item->playback_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if(pa_hashmap_put(profile_item->playback_devices, (void *)role, pulse_device) < 0) - return NULL; - } else { - if (!(profile_item->capture_devices)) - profile_item->capture_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if(pa_hashmap_put(profile_item->capture_devices, (void *)role, pulse_device) < 0) - return NULL; - } - - return profile_item; -} - -static dm_device_profile* _device_profile_add_sink(dm_device_profile *profile_item, const char *role, pa_sink *sink) { - if (!profile_item || !sink || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - - if (!(profile_item->playback_devices)) - profile_item->playback_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if(pa_hashmap_put(profile_item->playback_devices, (void *)role, sink) < 0) - return NULL; - - return profile_item; -} - -static dm_device_profile* _device_profile_remove_sink(dm_device_profile *profile_item, const char *role) { - if (!profile_item || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - pa_hashmap_remove(profile_item->playback_devices, role); - return profile_item; -} - -static dm_device_profile* _device_profile_add_source(dm_device_profile *profile_item, const char *role, pa_source *source) { - if (!profile_item || !source || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - - if (!(profile_item->capture_devices)) - profile_item->capture_devices = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if(pa_hashmap_put(profile_item->capture_devices, (void *)role, source) < 0) - return NULL; - - return profile_item; -} - -static int _device_profile_get_size(dm_device_profile *profile_item, unsigned int *playback_num, unsigned int *capture_num) { - if (!profile_item || !playback_num || !capture_num) { - pa_log_error("Invalid Parameter"); - return -1; - } - - if (!(profile_item->playback_devices)) - *playback_num = 0; - else - *playback_num = pa_hashmap_size(profile_item->playback_devices); - - if (!(profile_item->capture_devices)) - *capture_num = 0; - else - *capture_num = pa_hashmap_size(profile_item->capture_devices); - - return 0; -} - - -static dm_device_profile* _device_profile_remove_source(dm_device_profile *profile_item, const char *role) { - if (!profile_item || !(profile_item->capture_devices) || !device_role_is_valid(role)) { - pa_log_error("Invalid Parameter"); - return NULL; - } - pa_hashmap_remove(profile_item->capture_devices, role); - return profile_item; -} - -void _device_profile_set_state(dm_device_profile *profile_item, dm_device_direction_t direction, dm_device_state_t state) { - dm_device_state_t prev_state, new_state; - pa_assert(profile_item); - - prev_state = COMPOUND_STATE(profile_item); - pa_log_debug("previous playback_state : %d, capture_state : %d => state %d", profile_item->playback_state, profile_item->capture_state, prev_state); - if (direction & DM_DEVICE_DIRECTION_IN) - profile_item->capture_state = state; - if (direction & DM_DEVICE_DIRECTION_OUT) - profile_item->playback_state = state; - new_state = COMPOUND_STATE(profile_item); - pa_log_debug("new playback_state : %d, capture_state : %d => state %d", profile_item->playback_state, profile_item->capture_state, new_state); - - if (prev_state != new_state) { - notify_device_info_changed(profile_item->device_item, DM_DEVICE_CHANGED_INFO_STATE, profile_item->device_item->dm); - } -} - - -static int device_type_get_direction(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *identifier) { - struct device_type_info *type_info = NULL; - struct device_status_info *status_info; - dm_device_direction_t direction = 0, d_num = 0, d_idx = 0, correct_d_idx = 0; - - if (!dm || !device_type) { - pa_log_error("Invalid Parameter"); - return -1; - } - - - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("No type map for %s", device_type); - return -1; - } - - for (d_idx = 0; d_idx < DEVICE_DIRECTION_MAX; d_idx++) { - if (type_info->direction[d_idx] != DM_DEVICE_DIRECTION_NONE) { - correct_d_idx = d_idx; - d_num++; - } - } - - if (d_num == 1) { - direction = type_info->direction[correct_d_idx]; - } else { - /* Actually, only 'audio-jack' should come here */ - if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) { - status_info = _device_manager_get_status_info(dm->device_status, type_info->type, type_info->profile, identifier); - if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC) { - direction = DM_DEVICE_DIRECTION_BOTH; - } else if (status_info->detected_type == DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC) { - direction = DM_DEVICE_DIRECTION_OUT; - } else { - pa_log_debug("Cannot get audio jack device direction"); - return -1; - } - } else { - pa_log_error("Weird case, '%s' is not expected to have multiple direction", device_type); - return -1; - } - } - - return direction; -} - -static int pulse_device_get_device_type(void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class, const char **device_type, const char **device_profile, const char **device_name) { - pa_proplist *prop; - pa_sink *sink; - pa_source *source; - - pa_assert(pulse_device); - pa_assert(device_type); - pa_assert(device_profile); - - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - prop = sink->proplist; - } else { - source = (pa_source*) pulse_device; - prop = source->proplist; - } - - if (device_class == DM_DEVICE_CLASS_ALSA) { - if (pulse_device_is_usb(prop)) { - *device_type = DEVICE_TYPE_USB_AUDIO; - *device_profile = NULL; - *device_name = pa_proplist_gets(prop, PA_PROP_DEVICE_SERIAL); - } else { - pa_log_warn("This is alsa device, but not usb. really unknown device"); - return -1; - } - } else if (device_class == DM_DEVICE_CLASS_BT) { - *device_type = DEVICE_TYPE_BT; - *device_profile = DEVICE_PROFILE_BT_A2DP; - *device_name = pa_proplist_gets(prop, "bluez.alias"); - } else { - pa_log_warn("Invalid device type, neither alsa nor bluez"); - return -1; - } - - return 0; -} - -static dm_device_profile* _device_item_get_profile(dm_device *device_item, const char *profile) { - dm_device_profile *profile_item; - uint32_t profile_idx; - - if (!device_item || !device_item->profiles) - return NULL; - - PA_IDXSET_FOREACH(profile_item, device_item->profiles, profile_idx) { - if (!compare_device_profile(profile_item->profile, profile)) { - return profile_item; - } - } - return NULL; -} - -static dm_device_profile* _device_item_get_active_profile(dm_device *device_item) { - dm_device_profile *profile_item; - - if (!device_item || !device_item->profiles) - return NULL; - - if ((profile_item = pa_idxset_get_by_index(device_item->profiles, device_item->active_profile))) - return profile_item; - - - return NULL; -} - -static pa_sink* _device_manager_set_default_sink(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role) { - dm_device *device_item; - dm_device_profile *profile_item; - pa_sink *sink; - - if (!device_type || !role) { - pa_log_warn("Argument for set_default_sink invalid"); - return NULL; - } - - if (!(device_item = _device_manager_get_device(dm->device_list, device_type))) { - pa_log_warn("cannot get device item for %s", device_type); - return NULL; - } - if (!(profile_item = _device_item_get_profile(device_item, device_profile))) { - pa_log_warn("cannot get profile item for %s", device_profile); - return NULL; - } - - if (!(sink = pa_hashmap_get(profile_item->playback_devices, role))) { - pa_log_warn("cannot get sink for %s", role); - return NULL; - } - - sink = pa_namereg_set_default_sink(dm->core, sink); - return sink; -} - -static pa_source* _device_manager_set_default_source(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role) { - dm_device *device_item; - dm_device_profile *profile_item; - pa_source *source; - - if (!device_type || !role) { - pa_log_warn("Argument for set_default_source invalid"); - return NULL; - } - - if (!(device_item = _device_manager_get_device(dm->device_list, device_type))) { - pa_log_warn("cannot get device item for %s", device_type); - return NULL; - } - if (!(profile_item = _device_item_get_profile(device_item, device_profile))) { - pa_log_warn("cannot get profile item for %s", device_profile); - return NULL; - } - - if (!(source= pa_hashmap_get(profile_item->capture_devices, role))) { - pa_log_warn("cannot get source for %s", role); - return NULL; - } - - source = pa_namereg_set_default_source(dm->core, source); - return source; -} - -static dm_device_profile* handle_not_predefined_device_profile(void *pulse_device, pa_device_type_t pdt, const char *device_profile) { - dm_device_profile *profile_item = NULL; - dm_device_direction_t direc; - - pa_log_debug("Create device profile item %s", device_profile); - if (pdt == PA_DEVICE_TYPE_SINK) - direc = DM_DEVICE_DIRECTION_OUT; - else - direc = DM_DEVICE_DIRECTION_IN; - - if(!(profile_item = create_device_profile(device_profile, direc, NULL, NULL))) { - pa_log_error("create_device_profile failed"); - goto failed; - } - if (pdt == PA_DEVICE_TYPE_SINK) { - if (!(_device_profile_add_sink(profile_item, DEVICE_ROLE_NORMAL, pulse_device))) { - pa_log_error("failed to add sink"); - goto failed; - } - } else { - if (!(_device_profile_add_source(profile_item, DEVICE_ROLE_NORMAL, pulse_device))) { - pa_log_error("failed to add source"); - goto failed; - } - } - - return profile_item; -failed : - if (profile_item) - pa_xfree(profile_item); - return NULL; -} - - -static dm_device* handle_not_predefined_device(pa_device_manager *dm, void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class) { - dm_device_profile *profile_item = NULL; - const char *device_type, *device_profile, *device_name; - dm_device *device_item = NULL; - pa_source *sibling_source, *source; - pa_sink *sibling_sink, *sink; - - pa_assert(dm); - pa_assert(pulse_device); - - pa_log_debug("handle_not_predefined_device"); - - if (pulse_device_get_device_type(pulse_device, pdt, device_class, &device_type, &device_profile, &device_name) < 0) { - pa_log_warn("Cannot get device type of this device"); - return NULL; - } - - /* - Find opposite direction sink/sources on same device. - If Found, add sink or source to same device_item. - */ - if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) { - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - if ((sibling_source = pulse_device_get_opposite_sibling_device(sink, PA_DEVICE_TYPE_SINK))) { - if (sibling_source->device_item) { - device_item = (dm_device *) sibling_source->device_item; - profile_item = _device_item_get_profile(device_item, NULL); - if (!(_device_profile_add_sink(profile_item, DEVICE_ROLE_NORMAL, sink))) { - pa_log_error("failed to add sink beside sibling source"); - goto failed; - } - _device_profile_update_direction(profile_item); - notify_device_info_changed(device_item, DM_DEVICE_CHANGED_INFO_IO_DIRECTION, dm); - goto end; - } - } - } else { - source = (pa_source*) pulse_device; - if ((sibling_sink = pulse_device_get_opposite_sibling_device(source, PA_DEVICE_TYPE_SOURCE))) { - if (sibling_sink->device_item) { - device_item = (dm_device *) sibling_sink->device_item; - profile_item = _device_item_get_profile(device_item, NULL); - if (!(_device_profile_add_source(profile_item, DEVICE_ROLE_NORMAL, source))) { - pa_log_error("failed to add source beside sibling sink"); - goto failed; - } - _device_profile_update_direction(profile_item); - notify_device_info_changed(device_item, DM_DEVICE_CHANGED_INFO_IO_DIRECTION, dm); - goto end; - } - } - } - } - - if(!(profile_item = handle_not_predefined_device_profile(pulse_device, pdt, device_profile))) { - pa_log_error("failed to handle unknown device profile"); - goto failed; - } - _device_profile_update_direction(profile_item); - - if (device_class == DM_DEVICE_CLASS_BT) { - if((device_item = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT))) { - pa_log_debug("found bt device"); - _device_item_add_profile(device_item, profile_item, NULL, dm); - goto end; - } - } - - if (!(device_item = create_device_item(device_type, device_name, profile_item, dm))) { - pa_log_error("failed to create device item for not predefined device"); - goto failed; - } - -end: - - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - sink->device_item = device_item; - } else { - source = (pa_source *) pulse_device; - source->device_item = device_item; - } - - return device_item; - -failed: - pa_log_error("Failed to handle external device"); - if (profile_item) - pa_xfree(profile_item); - if (pdt == PA_DEVICE_TYPE_SINK) { - sink = (pa_sink *) pulse_device; - sink->device_item = device_item; - } else { - source = (pa_source *) pulse_device; - source->device_item = device_item; - } - - - return NULL; -} - -static pa_bool_t pulse_device_loaded_with_param(pa_core *core, pa_device_type_t pdt, const char *device_string, const char *params) { - pa_sink *sink; - pa_source *source; - uint32_t device_idx; - - pa_assert(core); - pa_assert(device_string); - - if (pdt == PA_DEVICE_TYPE_SINK) { - PA_IDXSET_FOREACH(sink, core->sinks, device_idx) { - if (pulse_device_class_is_monitor(sink->proplist)) - continue; - if (pa_streq(device_string, pulse_device_get_device_string(sink, pdt))) { - if (!compare_device_params_with_module_args(sink, pdt, params)) { - return TRUE; - } - } - } - } else { - PA_IDXSET_FOREACH(source, core->sources, device_idx) { - if (pulse_device_class_is_monitor(source->proplist)) - continue; - if (pa_streq(device_string, pulse_device_get_device_string(source, pdt))) { - if (!compare_device_params_with_module_args(source, pdt, params)) { - return TRUE; - } - } - } - } - return FALSE; -} - -static int device_type_get_pulse_devices(struct device_type_info *type_info, pa_hashmap **playback, pa_hashmap **capture, pa_device_manager *dm) { - struct device_file_info *file_info; - const char *device_string, *params, *role; - uint32_t device_idx; - pa_sink *sink; - pa_source *source; - void *state; - - pa_assert(type_info); - pa_assert(playback); - pa_assert(capture); - pa_assert(dm); - - if (type_info->playback_devices) { - *playback = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - PA_HASHMAP_FOREACH_KEY(device_string, type_info->playback_devices, state, role) { - if (!(file_info = _device_manager_get_file_info(dm->file_map->playback, device_string))) { - pa_log_error("No playback file map for '%s'", device_string); - goto failed; - } - - if (!(params = pa_hashmap_get(file_info->roles, role))) { - pa_log_error("No params for '%s:%s'", device_string, role); - goto failed; - } - - PA_IDXSET_FOREACH(sink, dm->core->sinks, device_idx) { - if (pulse_device_class_is_monitor(sink->proplist)) - continue; - if (pulse_device_same_device_string(sink, PA_DEVICE_TYPE_SINK, device_string)) { - if (!compare_device_params_with_module_args(sink, PA_DEVICE_TYPE_SINK, params)) { - pa_hashmap_put(*playback, (void *)role, sink); - pa_log_debug("role:%s <- sink:%s", role, sink->name); - break; - } - } - } - } - } - - - if (type_info->capture_devices) { - *capture = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - PA_HASHMAP_FOREACH_KEY(device_string, type_info->capture_devices, state, role) { - if (!(file_info = _device_manager_get_file_info(dm->file_map->capture, device_string))) { - pa_log_error("No capture file map for '%s'", device_string); - goto failed; - } - if (!(params = pa_hashmap_get(file_info->roles, role))) { - pa_log_error("No params for '%s:%s'", device_string, role); - goto failed; - } - PA_IDXSET_FOREACH(source, dm->core->sources, device_idx) { - if (pulse_device_class_is_monitor(source->proplist)) - continue; - if (pulse_device_same_device_string(source, PA_DEVICE_TYPE_SOURCE, device_string)) { - if (!compare_device_params_with_module_args(source, PA_DEVICE_TYPE_SOURCE, params)) { - pa_hashmap_put(*capture, (void *)role, source); - pa_log_debug("role:%s <- source:%s", role, source->name); - break; - } - } - } - } - } - - return 0; - -failed: - if (!(*playback)) - pa_hashmap_free(*playback); - if (!(*capture)) - pa_hashmap_free(*capture); - *playback = NULL; - *capture = NULL; - - return -1; -} - -static const char* device_type_info_get_device_string(struct device_type_info *type_info, const char *role, pa_device_type_t pdt) { - pa_assert(type_info); - pa_assert(role); - - if (pdt == PA_DEVICE_TYPE_SINK) { - if (type_info->playback_devices) - return pa_hashmap_get(type_info->playback_devices, role); - else - return NULL; - } else { - if (type_info->capture_devices) - return pa_hashmap_get(type_info->capture_devices, role); - else - return NULL; - } - -} - -static const char* device_file_info_get_role_with_params(struct device_file_info *file_info, const char *params) { - char *params_tmp, *role; - void *state; - - PA_HASHMAP_FOREACH_KEY(params_tmp, file_info->roles, state, role) { - if (!compare_device_params(params_tmp, params)) { - return role; - } - } - return NULL; -} - -static dm_device* handle_device_type_available(struct device_type_info *type_info, const char *name, pa_device_manager *dm) { - dm_device_profile *profile_item = NULL; - dm_device *device_item = NULL; - pa_bool_t made_newly = FALSE; - dm_device_direction_t direction; - pa_hashmap *playback = NULL, *capture = NULL; - - pa_assert(dm); - pa_assert(dm->type_infos); - - pa_log_debug("handle_device_type_available, type:%s, profile:%s, name:%s", type_info->type, type_info->profile, name); - - - - /* Directions of some types are not statically defined, ex) earjack */ - if ((direction = device_type_get_direction(dm, type_info->type, type_info->profile, NULL)) < 0) { - pa_log_error("Failed to get direction of %s.%s", type_info->type, type_info->profile); - return NULL; - } - pa_log_debug("Direction of %s.%s is %s", type_info->type, type_info->profile, device_direction_to_string(direction)); - - /* Get Sink/Sources for device_type, profile */ - if (device_type_get_pulse_devices(type_info, &playback, &capture, dm) < 0) { - pa_log_error("Failed to get sink/sources related to %s.%s", type_info->type, type_info->profile); - return NULL; - } - - /* Check whether Sink/Sources for direction of type are loaded */ - if ((((direction & DM_DEVICE_DIRECTION_IN) && !capture) || ((direction & DM_DEVICE_DIRECTION_OUT) && !playback))) { - pa_log_debug("Sink/Sources for %s.%s are not fully loaded yet", type_info->type, type_info->profile); - goto failed; - } - - profile_item = create_device_profile(type_info->profile, direction, playback, capture); - - if (!(device_item = _device_manager_get_device(dm->device_list, type_info->type))) { - pa_log_debug("No device item for %s, Create", type_info->type); - device_item = create_device_item(type_info->type, name, profile_item, dm); - made_newly = TRUE; - } else { - _device_item_add_profile(device_item, profile_item, NULL, dm); - } - - return device_item; - -failed : - if (playback) - pa_hashmap_free(playback); - if (capture) - pa_hashmap_free(capture); - if (device_item && made_newly) - pa_xfree(device_item); - if (profile_item) - pa_xfree(profile_item); - return NULL; -} - -/* FIXME to get identifier of physical device */ -static const char* pulse_device_get_identifier(void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class) { -/* - const char *sysfs_path; - - if (device_class == TIZEN_AUDIO_DEVICE_CLASS_ALSA) { - if (!(sysfs_path = pa_proplist_gets(sink->proplist, "sysfs.path"))) { - pa_log_warn("No sysfs.path for sink '%s'", sink->name); - return NULL; - } else { - return sysfs_path; - } - } else if (device_class == TIZEN_AUDIO_DEVICE_CLASS_BT) { - } - */ - return NULL; -} - -static void handle_predefined_device_loaded(void *pulse_device, pa_device_type_t pdt, dm_device_class_t device_class, const char *device_string, const char *role, pa_device_manager *dm) { - const char *identifier, *device_string_tmp; - struct device_type_info *type_info; - struct device_status_info *status_info; - uint32_t type_idx; - dm_device *device_item; - dm_device_profile *profile_item; - - pa_assert(pulse_device); - pa_assert(dm); - pa_assert(dm->file_map); - pa_assert(device_string); - pa_assert(role); - - pa_log_debug("Predefined device loaded, Type:%s, Class:%d, device_string:%s, role:%s", pdt == PA_DEVICE_TYPE_SINK ? "sink" : "source", device_class, device_string, role); - - identifier = pulse_device_get_identifier(pulse_device, pdt, device_class); - PA_IDXSET_FOREACH(type_info, dm->type_infos, type_idx) { - /* foreach matching types (which has device_string-role) */ - if ((device_string_tmp = device_type_info_get_device_string(type_info, role, pdt)) && pa_streq(device_string_tmp, device_string)) { - /* - Check device_item is already exists. - If already exists, add loaded sink or source to that. - */ - if((device_item = _device_manager_get_device(dm->device_list, type_info->type))) { - if((profile_item = _device_item_get_profile(device_item, type_info->profile))) { - pa_log_debug("device_item for %s.%s already exists", type_info->type, type_info->profile); - if (!_device_profile_add_pulse_device(profile_item, role, pulse_device, pdt)) - pa_log_error("add pulse device to profile_item failed"); - continue; - } - } - - /* Get status_info for device_type, profile*/ - if (!(status_info = _device_manager_get_status_info(dm->device_status, type_info->type, type_info->profile, identifier))) { - pa_log_error("%s.%s.%s doesn't have status_info", type_info->type, type_info->profile, identifier); - continue; - } - /* Only if device_type is on detected state*/ - if (status_info->detected == DEVICE_DETECTED) { - pa_log_debug("%s.%s type is detected status", type_info->type, type_info->profile); - - handle_device_type_available(type_info, NULL, dm); - } else { - pa_log_debug(" This type is not detected status"); - } - } - } -} - -static pa_bool_t _device_type_direction_available(struct device_type_info *type_info, dm_device_direction_t direction) { - int direc_idx; - - for (direc_idx = 0; direc_idx < DEVICE_DIRECTION_MAX; direc_idx++) { - if (type_info->direction[direc_idx] == direction) { - return TRUE; - } - } - - return FALSE; -} - -static void handle_sink_unloaded(pa_sink *sink, pa_device_manager *dm) { - dm_device_profile *profile_item= NULL; - struct device_type_info *type_info; - dm_device *device_item; - uint32_t device_idx = 0, profile_idx; - pa_sink *sink_iter = NULL; - void *state = NULL; - const char *role; - - if (!sink || !dm) { - pa_log_error("Invalid Paramter"); - return; - } - pa_assert(sink); - pa_assert(dm); - pa_assert(dm->device_list); - - pa_log_debug("Sink unloaded, Let's remove associated device_profiles with this sink"); - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - PA_IDXSET_FOREACH(profile_item, device_item->profiles, profile_idx) { - if (profile_item->playback_devices) { - PA_HASHMAP_FOREACH_KEY(sink_iter, profile_item->playback_devices, state, role) { - if (sink_iter == sink) { - unsigned int profile_playback_size = 0, profile_capture_size = 0, item_size = 0; - pa_log_debug("device '%s' have this sink", device_item->name); - _device_profile_get_size(profile_item, &profile_playback_size, &profile_capture_size); - item_size = _device_item_get_size(device_item); - pa_log_debug("profile playback size : %u, capture size : %u, item size : %u", profile_playback_size, profile_capture_size, item_size); - if (profile_playback_size == 1 && profile_capture_size == 0) { - if (item_size == 1) { - pa_log_debug("notify device disconnected"); - notify_device_connection_changed(device_item, FALSE, dm); - } - } - _device_profile_remove_sink(profile_item, role); - } - } - if (!pa_hashmap_size(profile_item->playback_devices)) { - pa_hashmap_free(profile_item->playback_devices); - profile_item->playback_devices = NULL; - - if (profile_item->direction == DM_DEVICE_DIRECTION_BOTH) { - type_info = _device_manager_get_type_info(dm->type_infos, profile_item->device_item->type, profile_item->profile); - if (_device_type_direction_available(type_info, DM_DEVICE_DIRECTION_IN)) { - profile_item->direction = DM_DEVICE_DIRECTION_IN; - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - } else { - _device_profile_update_direction(profile_item); - } - } - } - } -} - -static void handle_source_unloaded(pa_source *source, pa_device_manager *dm) { - dm_device_profile *profile_item= NULL; - struct device_type_info *type_info; - dm_device *device_item; - uint32_t device_idx = 0, profile_idx; - pa_source *source_iter = NULL; - void *state = NULL; - const char *role; - - if (!source|| !dm) { - pa_log_error("Invalid Paramter"); - return; - } - pa_assert(source); - pa_assert(dm); - pa_assert(dm->device_list); - - pa_log_debug("Source unloaded, Let's remove associated device_profiles with this source"); - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - PA_IDXSET_FOREACH(profile_item, device_item->profiles, profile_idx) { - if (profile_item->capture_devices) { - PA_HASHMAP_FOREACH_KEY(source_iter, profile_item->capture_devices, state, role) { - if (source_iter == source) { - unsigned int profile_playback_size = 0, profile_capture_size = 0, item_size = 0; - pa_log_debug("device '%s' have this source", device_item->name); - _device_profile_get_size(profile_item, &profile_playback_size, &profile_capture_size); - item_size = _device_item_get_size(device_item); - pa_log_debug("profile playback size : %u, capture size : %u, item size : %u", profile_playback_size, profile_capture_size, item_size); - if (profile_capture_size == 1 && profile_playback_size == 0) { - if (item_size == 1) { - pa_log_debug("notify device disconnected"); - notify_device_connection_changed(device_item, FALSE, dm); - } - } - - _device_profile_remove_source(profile_item, role); - } - } - - if (!pa_hashmap_size(profile_item->capture_devices)) { - pa_hashmap_free(profile_item->capture_devices); - profile_item->capture_devices= NULL; - - if (profile_item->direction == DM_DEVICE_DIRECTION_BOTH) { - type_info = _device_manager_get_type_info(dm->type_infos, profile_item->device_item->type, profile_item->profile); - if (_device_type_direction_available(type_info, DM_DEVICE_DIRECTION_OUT)) { - profile_item->direction = DM_DEVICE_DIRECTION_OUT; - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - } else { - if (!destroy_device_profile(profile_item, dm)) - break; - } - - } else { - _device_profile_update_direction(profile_item); - } - } - } - } -} - -static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, pa_device_manager *dm) { - const char *device_string = NULL, *role = NULL, *device_string_removed_params = NULL; - struct device_file_info *file_info = NULL; - dm_device_class_t device_class; - - pa_assert(c); - pa_assert(sink); - pa_assert(sink->proplist); - pa_assert(dm); - - if (pulse_device_class_is_monitor(sink->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; - } - - pa_log_debug("========== Sink Put Hook Callback '%s'(%d) ==========", sink->name, sink->index); - - device_class = pulse_device_get_class(sink, PA_DEVICE_TYPE_SINK); - pa_log_debug("Device Class '%s'", device_class_to_string(device_class)); - - if (!(device_string = pulse_device_get_device_string(sink, PA_DEVICE_TYPE_SINK))) { - return PA_HOOK_OK; - } else { - pa_log_debug("Device String '%s'", device_string); - } - - if (device_class == DM_DEVICE_CLASS_BT) { - handle_not_predefined_device(dm, sink, PA_DEVICE_TYPE_SINK, device_class); - } else if ((file_info = _device_manager_get_file_info(dm->file_map->playback, device_string))) { - /* module's argument includes device-string(ex. device=hw:0,0 ), - but key params for device_types hashmap is not. */ - if (!(device_string_removed_params = pulse_device_get_device_string_removed_argument(sink, PA_DEVICE_TYPE_SINK))) { - pa_log_debug("argument null"); - return PA_HOOK_OK; - } - if(!(role = device_file_info_get_role_with_params(file_info, device_string_removed_params))) { - pa_log_error("No role for %s", file_info->device_string); - return PA_HOOK_OK; - } - - handle_predefined_device_loaded(sink, PA_DEVICE_TYPE_SINK, device_class, device_string, role, dm); - } else { - pa_log_debug("Not-predefined device"); - handle_not_predefined_device(dm, sink, PA_DEVICE_TYPE_SINK, device_class); - } - - dump_device_list(dm); - return PA_HOOK_OK; -} - -static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, pa_device_manager *dm) { - pa_assert(c); - pa_assert(sink); - pa_assert(sink->proplist); - pa_assert(dm); - - if (pulse_device_class_is_monitor(sink->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; - } - - pa_log_debug("=========== Sink unlink Hook Callback '%s'(%d) ==========", sink->name, sink->index); - handle_sink_unloaded(sink, dm); - dump_device_list(dm); - return PA_HOOK_OK; -} - - -static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, pa_device_manager *dm) { - const char *device_string = NULL, *role = NULL, *device_string_removed_params = NULL; - struct device_file_info *file_info = NULL; - dm_device_class_t device_class; - - pa_assert(c); - pa_assert(source); - pa_assert(source->proplist); - pa_assert(dm); - - if (pulse_device_class_is_monitor(source->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; - } - - pa_log_debug("========== Source Put Hook Callback '%s'(%d) ==========", source->name, source->index); - - - device_class = pulse_device_get_class(source, PA_DEVICE_TYPE_SOURCE); - pa_log_debug("Device Class '%s'", device_class_to_string(device_class)); - - if (!(device_string = pulse_device_get_device_string(source, PA_DEVICE_TYPE_SOURCE))) { - return PA_HOOK_OK; - } else { - pa_log_debug("Device String '%s'", device_string); - } - - if (device_class == DM_DEVICE_CLASS_BT) { - handle_not_predefined_device(dm, source, PA_DEVICE_TYPE_SOURCE, device_class); - } else if ((file_info = _device_manager_get_file_info(dm->file_map->capture, device_string))) { - /* module's argument includes device-string(ex. device=hw:0,0 ), - but key params for device_types hashmap is not. */ - if (!(device_string_removed_params = pulse_device_get_device_string_removed_argument(source, PA_DEVICE_TYPE_SOURCE))) { - pa_log_debug("argument null"); - return PA_HOOK_OK; - } - if(!(role = device_file_info_get_role_with_params(file_info, device_string_removed_params))) { - pa_log_error("No role for %s", file_info->device_string); - return PA_HOOK_OK; - } - - handle_predefined_device_loaded(source, PA_DEVICE_TYPE_SOURCE, device_class, device_string, role, dm); - } else { - pa_log_debug("Not-predefined device"); - handle_not_predefined_device(dm, source, PA_DEVICE_TYPE_SOURCE, device_class); - } - - dump_device_list(dm); - return PA_HOOK_OK; -} - -static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, pa_device_manager *dm) { - pa_assert(c); - pa_assert(source); - pa_assert(source->proplist); - pa_assert(dm); - - if (pulse_device_class_is_monitor(source->proplist)) { - pa_log_debug("This device's class is monitor. Skip this"); - return PA_HOOK_OK; - } - - pa_log_debug("========== Source unlink Hook Callback '%s'(%d) ==========", source->name, source->index); - handle_source_unloaded(source, dm); - dump_device_list(dm); - - return PA_HOOK_OK; -} - -/* - Build params for load sink or source, and load it. -*/ - -static void* load_device(pa_core *c, pa_device_type_t pdt, const char *device_string, const char *device_params) { - const char *args = NULL; - const char *module_name; - pa_module *module; - pa_sink *sink; - pa_source *source; - uint32_t device_idx; - dm_device_class_t device_class; - - pa_assert(c); - pa_assert(device_string); - pa_assert(device_params); - - pa_log_debug("-------- load_%s_device : '%s' '%s' -------", pdt == PA_DEVICE_TYPE_SINK ? "playback" : "capture", device_string, device_params); - - device_class = device_string_get_class(device_string); - if (device_class <= DM_DEVICE_CLASS_NONE || device_class >= DM_DEVICE_CLASS_MAX) { - pa_log_warn("Invalid device_string '%s'", device_string); - return NULL; - } - - if (!(module_name = device_class_get_module_name(device_class, pdt))) { - pa_log_error("Get proper module name to load failed"); - return NULL; - } - if (!(args = build_params_to_load_device(device_string, device_params, device_class))) { - pa_log_error("Get proper module name to load failed"); - return NULL; - } - if (!(module = pa_module_load(c, module_name, args))) { - pa_log_error("Load module with name '%s' argu '%s' failed", module_name, args); - return NULL; - } - - - if (pdt == PA_DEVICE_TYPE_SINK) { - PA_IDXSET_FOREACH(sink, c->sinks, device_idx) { - if (sink->module == module) { - return sink; - } - } - } else { - PA_IDXSET_FOREACH(source, c->sources, device_idx) { - if (source->module == module) { - return source; - } - } - } - - return NULL; -} - -/* - Load sink/sources with information written in device-file map, - If there is several roles in same device-file, then first load with 'normal' params - and other roles with same params just reference it. if there is a role which is on same device - but have different params, then do not load it. (ex.uhqa) - This does not make device_item , just load sink or source. -*/ -static int load_builtin_devices(pa_device_manager *dm) { - void *role_state = NULL; - struct device_file_info *file_info = NULL; - const char *params, *role; - uint32_t file_idx; - - pa_assert(dm); - - pa_log_debug("\n==================== Load Builtin Devices ===================="); - - if (dm->file_map->playback) { - PA_IDXSET_FOREACH(file_info, dm->file_map->playback, file_idx) { - pa_log_debug("---------------- load sink for '%s' ------------------", file_info->device_string); - - /* if normal device exists , load first */ - if ((params = pa_hashmap_get(file_info->roles, DEVICE_ROLE_NORMAL))) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SINK, file_info->device_string, params)) - pa_log_error("load normal playback device failed"); - } - - PA_HASHMAP_FOREACH_KEY(params, file_info->roles, role_state, role) { - if (pa_streq(role, DEVICE_ROLE_NORMAL)) - continue; - pa_log_debug("load sink for role %s", role); - if (!pulse_device_loaded_with_param(dm->core, PA_DEVICE_TYPE_SINK, file_info->device_string, params)) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SINK, file_info->device_string, params)) - pa_log_error("load playback device failed"); - } - } - } - } - - - - if (dm->file_map->capture) { - PA_IDXSET_FOREACH(file_info, dm->file_map->capture, file_idx) { - pa_log_debug("---------------- load source for '%s' ------------------", file_info->device_string); - - /* if normal device exists , load first */ - if ((params = pa_hashmap_get(file_info->roles, DEVICE_ROLE_NORMAL))) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SOURCE, file_info->device_string, params)) pa_log_error("load normal capture device failed"); - } - - PA_HASHMAP_FOREACH_KEY(params, file_info->roles, role_state, role) { - if (pa_streq(role, DEVICE_ROLE_NORMAL)) - continue; - pa_log_debug("load source for role %s", role); - if (!pulse_device_loaded_with_param(dm->core, PA_DEVICE_TYPE_SOURCE, file_info->device_string, params)) { - if (!load_device(dm->core, PA_DEVICE_TYPE_SOURCE, file_info->device_string, params)) { - pa_log_error("load capture device failed"); - } - } - } - } - } - - return 0; -} - - -/***************** Parse json file *******************/ -static pa_hashmap* parse_device_role_object(json_object *device_role_o) { - pa_hashmap *roles = NULL; - const char *params, *device_role; - struct json_object_iterator it, it_end; - json_object *params_o; - - pa_assert(device_role_o); - pa_assert(json_object_is_type(device_role_o, json_type_object)); - - roles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if (!roles) { - pa_log_debug("hashmap new failed"); - goto failed; - } - - it = json_object_iter_begin(device_role_o); - it_end = json_object_iter_end(device_role_o); - - while (!json_object_iter_equal(&it, &it_end)) { - device_role = json_object_iter_peek_name(&it); - params_o = json_object_iter_peek_value(&it); - - if (!(params = json_object_get_string(params_o))) { - pa_log_debug("There is no device params for role '%s'", device_role); - } - pa_log_debug("[DEBUG_PARSE] role '%s' - params '%s'", device_role, params); - if (device_role_is_valid(device_role)) { - if (pa_hashmap_put(roles, (void *)device_role, (void *)params)) { - pa_log_error("put new role to hashmap faild"); - goto failed; - } - } else { - pa_log_error("Invalid device role '%s'", device_role); - } - - json_object_iter_next(&it); - } - - if (pa_hashmap_size(roles) == 0) { - pa_log_warn("There is no role for device.. free hashmap"); - pa_hashmap_free(roles); - roles = NULL; - } - - return roles; - -failed: - if (roles) - pa_hashmap_free(roles); - - return NULL; -} - -static struct device_file_info* parse_device_file_object(json_object *device_file_o, const char **device_string_key) { - pa_hashmap *roles = NULL; - json_object *device_file_prop_o = NULL; - const char *device_string = NULL; - struct device_file_info *file_info = NULL; - - pa_assert(device_file_o); - pa_assert(device_string_key); - pa_assert(json_object_is_type(device_file_o, json_type_object)); - - if ((device_file_prop_o = json_object_object_get(device_file_o, "device-string")) && json_object_is_type(device_file_prop_o, json_type_string)) { - if ((device_string = json_object_get_string(device_file_prop_o))) { - pa_log_debug("[DEBUG_PARSE] ---------------- Device File '%s' ----------------", device_string); - } else { - pa_log_error("Get device-string failed"); - return NULL; - } - } else { - pa_log_error("Get device-string object failed"); - return NULL; - } - - if ((device_file_prop_o = json_object_object_get(device_file_o, DEVICE_TYPE_PROP_ROLE))) { - if (!(roles = parse_device_role_object(device_file_prop_o))) { - pa_log_error("Parse device role for '%s' failed", device_string); - goto failed; - } - } else { - pa_log_error("Get device role object failed"); - } - - file_info = pa_xmalloc0(sizeof(struct device_file_info)); - file_info->device_string = device_string; - file_info->device_types = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - file_info->roles = roles; - -// *device_string_key = device_string; - - return file_info; - -failed : - if (roles) - pa_xfree(roles); - - return NULL; -} - -static pa_idxset* parse_device_file_array_object(json_object *device_file_array_o) { - int device_file_num, device_file_idx; - struct device_file_info *file_info = NULL; - json_object *device_file_o = NULL; - pa_idxset *device_files = NULL; - const char *device_string = NULL; - - pa_assert(device_file_array_o); - pa_assert(json_object_is_type(device_file_array_o, json_type_array)); - - device_files = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - - device_file_num = json_object_array_length(device_file_array_o); - for (device_file_idx = 0; device_file_idx < device_file_num; device_file_idx++) { - if ((device_file_o = json_object_array_get_idx(device_file_array_o, device_file_idx)) && json_object_is_type(device_file_o, json_type_object)) { - if ((file_info = parse_device_file_object(device_file_o, &device_string))) { - pa_idxset_put(device_files, file_info, NULL); - } else { - pa_log_error("parse device file object failed"); - goto failed; - } - } else { - pa_log_error("Get device file object failed"); - goto failed; - } - } - - if (pa_idxset_size(device_files) == 0) { - pa_idxset_free(device_files, NULL); - device_files = NULL; - } - return device_files; -failed: - if (device_files) - pa_xfree(device_files); - return NULL; -} - -static struct device_file_map *parse_device_file_map() { - struct device_file_map *file_map = NULL; - json_object *o, *device_files_o; - json_object *playback_devices_o = NULL, *capture_devices_o = NULL; - - pa_log_debug("\n[DEBUG_PARSE] ==================== Parse device files ===================="); - - o = json_object_from_file(DEVICE_MAP_FILE); - - if (is_error(o)) { - pa_log_error("Read device-map file failed"); - return NULL; - } - - file_map = pa_xmalloc0(sizeof(struct device_file_map)); - - if ((device_files_o = json_object_object_get(o, DEVICE_FILE_OBJECT)) && json_object_is_type(device_files_o, json_type_object)) { - if ((playback_devices_o = json_object_object_get(device_files_o, "playback-devices"))) { - pa_log_debug("[DEBUG_PARSE] ----------------- Playback Device Files ------------------"); - file_map->playback = parse_device_file_array_object(playback_devices_o); - } - if ((capture_devices_o = json_object_object_get(device_files_o, "capture-devices"))) { - pa_log_debug("[DEBUG_PARSE] ----------------- Capture Device Files ------------------"); - file_map->capture = parse_device_file_array_object(capture_devices_o); - } - } - else { - pa_log_error("Get device files object failed"); - return NULL; - } - - return file_map; -} - - -static pa_hashmap* parse_device_role_map(json_object *device_role_map_o) { - pa_hashmap *roles = NULL; - const char *device_string, *device_role; - struct json_object_iterator it, it_end; - json_object *device_string_o; - - pa_assert(device_role_map_o); - pa_assert(json_object_is_type(device_role_map_o, json_type_object)); - - roles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - - it = json_object_iter_begin(device_role_map_o); - it_end = json_object_iter_end(device_role_map_o); - - while (!json_object_iter_equal(&it, &it_end)) { - device_role = json_object_iter_peek_name(&it); - device_string_o = json_object_iter_peek_value(&it); - - if (!(device_string = json_object_get_string(device_string_o))) { - pa_log_debug("There is no device string for role '%s'", device_role); - } - pa_log_debug("[DEBUG_PARSE] role '%s' - device_string '%s'", device_role, device_string); - if (device_role_is_valid(device_role)) { - if (pa_hashmap_put(roles, (void *)device_role, (void *)device_string)) { - pa_log_error("put new role to hashmap faild"); - goto failed; - } - } else { - pa_log_error("Invalid device role '%s'", device_role); - goto failed; - } - - json_object_iter_next(&it); - } - - return roles; - -failed : - if (roles) - pa_xfree(roles); - - return NULL; -} - - - -static pa_idxset* parse_device_type_infos() { - json_object *o, *device_array_o = NULL; - int device_type_num = 0; - int device_type_idx = 0; - json_bool builtin; - struct device_type_info *type_info = NULL; - //pa_hashmap *type_infos = NULL; - pa_idxset *type_infos = NULL; - - o = json_object_from_file(DEVICE_MAP_FILE); - if (is_error(o)) { - pa_log_error("Read device-map file failed"); - return NULL; - } - - pa_log_debug("\n[DEBUG_PARSE] ==================== Parse device types ===================="); - type_infos = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - - if ((device_array_o = json_object_object_get(o, DEVICE_TYPE_OBJECT)) && json_object_is_type(device_array_o, json_type_array)) { - device_type_num = json_object_array_length(device_array_o); - for (device_type_idx = 0; device_type_idx < device_type_num ; device_type_idx++) { - json_object *device_o; - - if ((device_o = json_object_array_get_idx(device_array_o, device_type_idx)) && json_object_is_type(device_o, json_type_object)) { - json_object *device_prop_o; - json_object *array_item_o; - int array_len, array_idx; - const char *device_type = NULL, *device_profile = NULL; - type_info = pa_xmalloc0(sizeof(struct device_type_info)); - - if ((device_prop_o = json_object_object_get(device_o, "device-type")) && json_object_is_type(device_prop_o, json_type_string)) { - device_type = json_object_get_string(device_prop_o); - pa_log_debug("[DEBUG_PARSE] ---------------- Parse device '%s' ----------------", device_type); - type_info->type = device_type; - } else { - pa_log_error("Get device type failed"); - goto failed; - } - if ((device_prop_o = json_object_object_get(device_o, "profile")) && json_object_is_type(device_prop_o, json_type_string)) { - device_profile = json_object_get_string(device_prop_o); - pa_log_debug("[DEBUG_PARSE] Profile: %s", device_profile); - type_info->profile= device_profile; - } else { - pa_log_debug("no device-profile"); - } - - - if ((device_prop_o = json_object_object_get(device_o, DEVICE_TYPE_PROP_BUILTIN)) && json_object_is_type(device_prop_o, json_type_boolean)) { - builtin = json_object_get_boolean(device_prop_o); - pa_log_debug("[DEBUG_PARSE] builtin: %d", builtin); - type_info->builtin = builtin; - } else { - pa_log_error("Get device prop '%s' failed", DEVICE_TYPE_PROP_BUILTIN); - } - - if ((device_prop_o = json_object_object_get(device_o, DEVICE_TYPE_PROP_DIRECTION)) && json_object_is_type(device_prop_o, json_type_array)) { - const char *direction; - array_len = json_object_array_length(device_prop_o); - if ((array_len = json_object_array_length(device_prop_o)) > DEVICE_DIRECTION_MAX) { - pa_log_error("Invalid case, The number of direction is too big (%d)", array_len); - goto failed; - } - for (array_idx = 0; array_idx < array_len; array_idx++) { - if ((array_item_o = json_object_array_get_idx(device_prop_o, array_idx)) && json_object_is_type(array_item_o, json_type_string)) { - direction = json_object_get_string(array_item_o); - pa_log_debug("[DEBUG_PARSE] direction : %s", direction); - type_info->direction[array_idx] = device_direction_to_int(direction); - } - } - } else { - pa_log_error("Get device prop '%s' failed", DEVICE_TYPE_PROP_DIRECTION); - } - - if ((device_prop_o = json_object_object_get(device_o, "avail-condition")) && json_object_is_type(device_prop_o, json_type_array)) { - const char *avail_cond; - if ((array_len = json_object_array_length(device_prop_o)) > DEVICE_AVAIL_COND_NUM_MAX) { - pa_log_error("Invalid case, The number of avail-condition is too big (%d)", array_len); - goto failed; - } - for (array_idx = 0; array_idx < array_len; array_idx++) { - if ((array_item_o = json_object_array_get_idx(device_prop_o, array_idx)) && json_object_is_type(array_item_o, json_type_string)) { - avail_cond = json_object_get_string(array_item_o); - pa_log_debug("[DEBUG_PARSE] avail-condition : %s", avail_cond); - strncpy(type_info->avail_condition[array_idx], avail_cond, DEVICE_AVAIL_COND_STR_MAX); - } - } - } else { - pa_log_error("Get device prop 'avail-condition' failed"); - } - - if ((device_prop_o = json_object_object_get(device_o, "playback-devices")) && json_object_is_type(device_prop_o, json_type_object)) { - pa_log_debug("[DEBUG_PARSE] ------ playback devices ------"); - type_info->playback_devices = parse_device_role_map(device_prop_o); - } - - if ((device_prop_o = json_object_object_get(device_o, "capture-devices")) && json_object_is_type(device_prop_o, json_type_object)) { - pa_log_debug("[DEBUG_PARSE] ------ capture devices ------"); - type_info->capture_devices = parse_device_role_map(device_prop_o); - } - pa_idxset_put(type_infos, type_info, NULL); - - } - else { - pa_log_debug("Get device type object failed"); - } - } - } - else { - pa_log_debug("Get device type array object failed"); - } - return type_infos; - -failed : - if (type_infos) - pa_xfree(type_infos); - - return NULL; -} - -/* - Handle device connection detected through dbus. - First, update device-status hashmap. - And if correnspondent sink/sources for device_type exist, should make device_item and notify it. - Use [device_type->roles] mappings in sink/source for find proper sink/source. -*/ -static int handle_device_connected(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *name, const char *identifier, int detected_type) { - struct device_status_info *status_info; - struct device_type_info *type_info; - dm_device *device_item; - dm_device_profile *profile_item; - - pa_assert(dm); - pa_assert(dm->device_status); - - pa_log_debug("Device %s connected, detected_type : %d", device_type, detected_type); - if (!(status_info = _device_manager_get_status_info(dm->device_status, device_type, device_profile, identifier))) { - pa_log_error("No device_status_info for %s.%s", device_type, device_profile); - return -1; - } - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = detected_type; - - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("Failed to get type_info for %s.%s", device_type, device_profile); - } - - if((device_item = _device_manager_get_device(dm->device_list, type_info->type))) { - if((profile_item = _device_item_get_profile(device_item, type_info->profile))) { - pa_log_debug("device_item for %s.%s already exists", type_info->type, type_info->profile); - return 0; - } - } - - handle_device_type_available(type_info, name, dm); - - return 0; -} - -/* - Handle device disconnection detected through dbus. - First, update device-status hashmap. - And if there is device_item which has the device_type, remove it. -*/ -static int handle_device_disconnected(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *identifier) { - dm_device_profile *profile_item; - dm_device *device_item; - struct device_status_info *status_info; - uint32_t device_idx = 0; - - pa_assert(dm); - pa_assert(dm->device_status); - - pa_log_debug("Device %s disconnected", device_type); - if (!(status_info = _device_manager_get_status_info(dm->device_status, device_type, device_profile, identifier))) { - pa_log_error("No device_status_info for %s.%s", device_type, device_profile); - return -1; - } - status_info->detected = DEVICE_NOT_DETECTED; - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if (pa_streq(device_item->type, device_type)) { - if((profile_item = _device_item_get_profile(device_item, device_profile))) { - if (_device_item_get_size(device_item) == 1) - notify_device_connection_changed(device_item, FALSE, dm); - destroy_device_profile(profile_item, dm); - } else { - pa_log_debug("no matching profile"); - } - } - } - - return 0; -} - - -/* - look detected status which is external value, make conversion to internal consistent value, and handle it - device_type, device_profile : which type of device is detected - identifier : identifier among same device types for support multi-device -*/ -static int handle_device_status_changed(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *name, const char *identifier, int detected_status) { - pa_assert(dm); - pa_assert(device_type_is_valid(device_type)); - - pa_log_debug("Device Status Changed, type : '%s', profile : '%s', identifier : '%s', detected_status : %d", device_type, device_profile, identifier, detected_status); - if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) { - if (detected_status == EARJACK_DISCONNECTED) { - handle_device_disconnected(dm, device_type, device_profile, identifier); - } else if (detected_status == EARJACK_TYPE_SPK_ONLY) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC); - } else if (detected_status == EARJACK_TYPE_SPK_WITH_MIC) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC); - } else { - pa_log_warn("Got invalid audio-jack detected value"); - return -1; - } - } else if (pa_streq(device_type, DEVICE_TYPE_BT) && device_profile && pa_streq(device_profile, DEVICE_PROFILE_BT_SCO)) { - if (detected_status == BT_SCO_DISCONNECTED) { - handle_device_disconnected(dm, device_type, device_profile, identifier); - } else if (detected_status == BT_SCO_CONNECTED) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_BT_SCO); - } else { - pa_log_warn("Got invalid bt-sco detected value"); - return -1; - } - } else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) { - if (detected_status == HDMI_AUDIO_DISCONNECTED) { - handle_device_disconnected(dm, device_type, device_profile, identifier); - } else if (detected_status >= HDMI_AUDIO_AVAILABLE) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_HDMI); - } else if (detected_status == HDMI_AUDIO_NOT_AVAILABLE) { - pa_log_debug("HDMI audio not available"); - return -1; - } else { - pa_log_warn("Got invalid hdmi detected value"); - return -1; - } - } else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) { - if (detected_status == FORWARDING_DISCONNECTED) { - handle_device_disconnected(dm, device_type, device_profile, identifier); - } else if (detected_status == FORWARDING_CONNECTED) { - handle_device_connected(dm, device_type, device_profile, name, identifier, DEVICE_DETECTED_FORWARDING); - } else { - pa_log_warn("Got invalid mirroring detected value"); - return -1; - } - } else { - pa_log_debug("unknown device type"); - } - return 0; -} - -/* - Initialize device-status idxset. - This is for device-status detected through dbus. - So, if device_type is not detected through dbus, let's initialize them to detected. (ex. spk, rcv,...) - If not, initialize to not detected. -*/ -static pa_idxset* device_type_status_init(pa_idxset *type_infos) { - int avail_cond_idx = 0, avail_cond_num = 0, correct_avail_cond = 0; - struct device_type_info *type_info; - struct device_status_info *status_info; - pa_idxset *device_status; - uint32_t type_idx; - - pa_assert(type_infos); - - pa_log_debug("\n==================== Init Device Status ===================="); - - device_status = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - - PA_IDXSET_FOREACH(type_info, type_infos, type_idx) { - status_info = (struct device_status_info *) pa_xmalloc0(sizeof(struct device_status_info)); - status_info->type = type_info->type; - status_info->profile = type_info->profile; - if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_AUDIO_JACK, NULL)) { - int earjack_status = 0; - if (vconf_get_int(VCONFKEY_SYSMAN_EARJACK, &earjack_status) < 0) { - status_info->detected = DEVICE_NOT_DETECTED; - pa_log_error("Get earjack status failed"); - } else if (earjack_status == EARJACK_DISCONNECTED) { - status_info->detected = DEVICE_NOT_DETECTED; - } else if (earjack_status == EARJACK_TYPE_SPK_ONLY) { - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = DEVICE_DETECTED_AUDIO_JACK_OUT_DIREC; - } else if (earjack_status == EARJACK_TYPE_SPK_WITH_MIC) { - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = DEVICE_DETECTED_AUDIO_JACK_BOTH_DIREC; - } else { - status_info->detected = DEVICE_NOT_DETECTED; - pa_log_warn("Unknown earjack status : %d", earjack_status); - } - } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO)) { - } else if (!compare_device_type(status_info->type, status_info->profile, DEVICE_TYPE_FORWARDING, NULL)) { - int miracast_wfd_status = 0; - if (vconf_get_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &miracast_wfd_status) < 0) { - status_info->detected = DEVICE_NOT_DETECTED; - pa_log_error("Get mirroring status failed"); - } else if (miracast_wfd_status == FORWARDING_DISCONNECTED) { - status_info->detected = DEVICE_NOT_DETECTED; - } else if (miracast_wfd_status == FORWARDING_CONNECTED) { - status_info->detected = DEVICE_DETECTED; - status_info->detected_type = DEVICE_DETECTED_FORWARDING; - } else { - status_info->detected = DEVICE_NOT_DETECTED; - pa_log_warn("Unknown mirroring status : %d", miracast_wfd_status); - } - } else { - for (avail_cond_idx = 0, avail_cond_num = 0; avail_cond_idx < DEVICE_AVAIL_COND_NUM_MAX; avail_cond_idx++) { - if (pa_streq(type_info->avail_condition[avail_cond_idx], "")) { - avail_cond_num++; - } - } - if (avail_cond_num == 1 && pa_streq(type_info->avail_condition[correct_avail_cond], DEVICE_AVAIL_CONDITION_STR_PULSE)) { - /* device types which don't need to be detected from other-side, let's just set 'detected'*/ - status_info->detected = DEVICE_DETECTED; - } else { - status_info->detected = DEVICE_NOT_DETECTED; - } - } - - pa_log_debug("Set %-17s %s detected", type_info->type, (status_info->detected == DEVICE_DETECTED) ? "" : "not"); - pa_idxset_put(device_status, status_info, NULL); - } - return device_status; -} - -static int device_list_init(pa_device_manager *dm) { - pa_assert(dm); - - dm->device_list = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - - return 0; -} - -#ifdef HAVE_DBUS - -static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DBusMessage *s, void *userdata) { - DBusError error; - int status = 0; - pa_device_manager *dm = (pa_device_manager *) userdata; - - pa_assert(userdata); - - if (dbus_message_get_type(s) != DBUS_MESSAGE_TYPE_SIGNAL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - pa_log_info("Dbus device detect handler received msg"); - - pa_log_debug("path : %s", dbus_message_get_path(s)); - pa_log_debug("interface : %s", dbus_message_get_interface(s)); - pa_log_debug("member : %s", dbus_message_get_member(s)); - pa_log_debug("siganature : %s", dbus_message_get_signature(s)); - - dbus_error_init(&error); - - if (dbus_message_is_signal(s, DBUS_INTERFACE_DEVICED_SYSNOTI, "ChangedEarjack")) { - if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { - goto fail; - } else { - handle_device_status_changed(dm, DEVICE_TYPE_AUDIO_JACK, NULL, NULL, NULL, status); - } - } else if (dbus_message_is_signal(s, DBUS_INTERFACE_DEVICED_SYSNOTI, "ChangedHDMIAudio")) { - if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { - goto fail; - } else { - handle_device_status_changed(dm, DEVICE_TYPE_HDMI, NULL, NULL, NULL, status); - } - } else if (dbus_message_is_signal(s, DBUS_INTERFACE_MIRRORING_SERVER, "miracast_wfd_source_status_changed")) { - if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { - goto fail; - } else { - handle_device_status_changed(dm, DEVICE_TYPE_FORWARDING, NULL, NULL, NULL, status); - } - } else if (dbus_message_is_signal(s, DBUS_INTERFACE_BLUEZ_HEADSET, "PropertyChanged")) { - DBusMessageIter msg_iter, variant_iter; - char *property_name; - - pa_log_debug("Got %s PropertyChanged signal", DBUS_INTERFACE_BLUEZ_HEADSET); - dbus_message_iter_init(s, &msg_iter); - if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_STRING) { - pa_log_error("Property name not string"); - goto fail; - } - dbus_message_iter_get_basic(&msg_iter, &property_name); - pa_log_debug("property name : %s", property_name); - - if (!dbus_message_iter_next(&msg_iter)) { - pa_log_debug("Property value missing"); - goto fail; - } - - if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_VARIANT) { - pa_log_debug("Property value not a variant."); - goto fail; - } - - dbus_message_iter_recurse(&msg_iter, &variant_iter); - - if (DBUS_TYPE_BOOLEAN == dbus_message_iter_get_arg_type(&variant_iter)) { - dbus_bool_t value; - char *name; - dbus_message_iter_get_basic(&variant_iter, &value); - if (pa_streq(property_name, "Playing")) { - dm_device *device_item; - pa_log_debug("SCO Playing : %d", value); - if ((device_item = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT))) { - if (value) - _device_item_set_active_profile(device_item, DEVICE_PROFILE_BT_SCO); - else - _device_item_set_active_profile_auto(device_item); - } - } else if (pa_streq(property_name, "Connected")) { - pa_log_debug("HFP Connection : %d", value); - if (value) { - method_call_bt_get_name(c, dbus_message_get_path(s), &name); - status = BT_SCO_CONNECTED; - } else { - status = BT_SCO_DISCONNECTED; - } - handle_device_status_changed(dm, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, name, NULL, status); - } - } - } else { - pa_log_info("Unknown message, not handle it"); - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - pa_log_debug("Dbus Message handled"); - - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_HANDLED; - -fail: - pa_log_error("Fail to handle dbus signal"); - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static int watch_signals(pa_device_manager *dm) { - DBusError error; - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - dbus_error_init(&error); - - pa_log_debug("Watch Dbus signals"); - - if (!dbus_connection_add_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm, NULL)) { - pa_log_error("Unable to add D-Bus filter : %s: %s", error.name, error.message); - goto fail; - } - - if (pa_dbus_add_matches(pa_dbus_connection_get(dm->dbus_conn), &error, FILTER_DEVICED_SYSNOTI, FILTER_SOUND_SERVER, FILTER_BLUEZ, FILTER_MIRRORING, NULL) < 0) { - pa_log_error("Unable to subscribe to signals: %s: %s", error.name, error.message); - goto fail; - } - return 0; - -fail: - dbus_error_free(&error); - return -1; -} - -static void unwatch_signals(pa_device_manager *dm) { - pa_log_debug("Unwatch Dbus signals"); - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - pa_dbus_remove_matches(pa_dbus_connection_get(dm->dbus_conn), FILTER_DEVICED_SYSNOTI, FILTER_SOUND_SERVER, FILTER_BLUEZ, FILTER_MIRRORING, NULL); - dbus_connection_remove_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm); -} - - -static void send_device_connected_signal(dm_device *device_item, pa_bool_t connected, pa_device_manager *dm) { - DBusMessage *signal_msg; - DBusMessageIter msg_iter, device_iter; - dm_device_profile *profile_item; - dbus_bool_t _connected = connected; - dm_device_state_t compound_state; - dbus_int32_t device_id; - - pa_assert(device_item); - pa_assert(device_item->profiles); - pa_assert(dm); - - pa_log_debug("Send following device %s signal", connected ? "Connected" : "Disconnected"); - dump_device_info(device_item); - - pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected")); - dbus_message_iter_init_append(signal_msg, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); - if (!(profile_item = _device_item_get_active_profile(device_item))) { - pa_log_error("active profile null"); - return; - } - - device_id = (dbus_int32_t) device_item->id; - compound_state = COMPOUND_STATE(profile_item); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &profile_item->direction); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->name); - pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter)); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected); - - - pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); - dbus_message_unref(signal_msg); -} - -static void send_device_info_changed_signal(dm_device *device_item, int changed_type, pa_device_manager *dm) { - DBusMessage *signal_msg; - DBusMessageIter msg_iter, device_iter; - dm_device_profile *profile_item; - dm_device_state_t compound_state; - dbus_int32_t device_id; - - pa_assert(device_item); - pa_assert(device_item->profiles); - pa_assert(dm); - - pa_log_debug("Send folling device info changed signal"); - dump_device_info(device_item); - - pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceInfoChanged")); - dbus_message_iter_init_append(signal_msg, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); - if (!(profile_item = _device_item_get_active_profile(device_item))) { - pa_log_error("active profile null"); - return; - } - device_id = (dbus_int32_t) device_item->id; - compound_state = COMPOUND_STATE(profile_item); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &profile_item->direction); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->name); - pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter)); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &changed_type); - - - pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); - dbus_message_unref(signal_msg); -} - -static void notify_device_connection_changed(dm_device *device_item, pa_bool_t connected, pa_device_manager *dm) { - pa_device_manager_hook_data_for_conn_changed hook_data; - - send_device_connected_signal(device_item, connected, dm); - hook_data.is_connected = connected; - hook_data.device = device_item; - pa_hook_fire(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), &hook_data); -} - -static void notify_device_info_changed(dm_device *device_item, dm_device_changed_info_t changed_type, pa_device_manager *dm) { - pa_device_manager_hook_data_for_info_changed hook_data; - - send_device_info_changed_signal(device_item, changed_type, dm); - - hook_data.changed_info = changed_type; - hook_data.device = device_item; - pa_hook_fire(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), &hook_data); -} - -static pa_bool_t device_item_match_for_mask(dm_device *device_item, int device_flags, pa_device_manager *dm) { - dm_device_profile *profile_item = NULL; - pa_bool_t match = FALSE; - int need_to_check_for_io_direction = device_flags & DEVICE_IO_DIRECTION_FLAGS; - int need_to_check_for_state = device_flags & DEVICE_STATE_FLAGS; - int need_to_check_for_type = device_flags & DEVICE_TYPE_FLAGS; - - pa_assert(device_item); - - if (device_flags == DEVICE_ALL_FLAG) - return TRUE; - - profile_item = _device_item_get_active_profile(device_item); - if (need_to_check_for_io_direction) { - if ((profile_item->direction == DM_DEVICE_DIRECTION_IN) && (device_flags & DEVICE_IO_DIRECTION_IN_FLAG)) match = TRUE; - else if ((profile_item->direction == DM_DEVICE_DIRECTION_OUT) && (device_flags & DEVICE_IO_DIRECTION_OUT_FLAG)) match = TRUE; - else if ((profile_item->direction == DM_DEVICE_DIRECTION_BOTH) && (device_flags & DEVICE_IO_DIRECTION_BOTH_FLAG)) match = TRUE; - if (match) { - if (!need_to_check_for_state && !need_to_check_for_type) return TRUE; - } else { - return FALSE; - } - } - if (need_to_check_for_state) { - match = FALSE; - if ((COMPOUND_STATE(profile_item)== DM_DEVICE_STATE_DEACTIVATED) && (device_flags & DEVICE_STATE_DEACTIVATED_FLAG)) - match = TRUE; - else if ((COMPOUND_STATE(profile_item) == DM_DEVICE_STATE_ACTIVATED) && (device_flags & DEVICE_STATE_ACTIVATED_FLAG)) - match = TRUE; - if (match) { - if (!need_to_check_for_type) - return TRUE; - } else { - return FALSE; - } - } - if (need_to_check_for_type) { - struct device_type_info *type_info; - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_item->type, profile_item->profile))) { - pa_log_error("No type_info for %s.%s", device_item->type, profile_item->profile); - return FALSE; - } - if (type_info->builtin && (device_flags & DEVICE_TYPE_INTERNAL_FLAG)) - return TRUE; - else if (!type_info->builtin && (device_flags & DEVICE_TYPE_EXTERNAL_FLAG)) - return TRUE; - } - - return FALSE; -} - - -static int method_call_bt_sco(DBusConnection *conn, pa_bool_t onoff) { - DBusMessage *msg, *reply; - DBusError err; - const char *method; - - method = onoff ? "Play" : "Stop"; - if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_HFP_AGENT, DBUS_OBJECT_HFP_AGENT, DBUS_INTERFACE_HFP_AGENT, method))) { - pa_log_error("dbus method call failed"); - return -1; - } - - dbus_error_init(&err); - if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) { - pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, method, err.message); - dbus_error_free(&err); - return -1; - } - - dbus_message_unref(reply); - return 0; -} - -static int method_call_bt_sco_get_property(DBusConnection *conn, pa_bool_t *is_wide_band, pa_bool_t *nrec) { - DBusMessage *msg, *reply; - DBusMessageIter reply_iter, reply_iter_entry; - DBusError err; - unsigned int codec; - const char *property; - - pa_assert(conn); - - if (!is_wide_band && !nrec) { - return -1; - } - - if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_HFP_AGENT, DBUS_OBJECT_HFP_AGENT, DBUS_INTERFACE_HFP_AGENT, "GetProperties"))) { - pa_log_error("dbus method call failed"); - return -1; - } - - dbus_error_init(&err); - if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) { - pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_HFP_AGENT, "GetProperties", err.message); - dbus_error_free(&err); - return -1; - } - - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) { - pa_log_error("Cannot get reply argument"); - return -1; - } - - dbus_message_iter_recurse(&reply_iter, &reply_iter_entry); - - while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) { - DBusMessageIter dict_entry, dict_entry_val; - dbus_message_iter_recurse(&reply_iter_entry, &dict_entry); - dbus_message_iter_get_basic(&dict_entry, &property); - pa_log_debug("String received = %s", property); - if (property) { - if (pa_streq("codec", property) && is_wide_band) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_UINT32) - continue; - dbus_message_iter_get_basic(&dict_entry_val, &codec); - pa_log_debug("Codec = [%d]", codec); - *is_wide_band= codec == BT_MSBC_CODEC_ID ? TRUE : FALSE; - } else if (pa_streq("nrec", property) && nrec) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_BOOLEAN) - continue; - dbus_message_iter_get_basic(&dict_entry_val, nrec); - pa_log_debug("nrec= [%d]", *nrec); - } - } - dbus_message_iter_next(&reply_iter_entry); - } - - - dbus_message_unref(reply); - return 0; -} - - -static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name) { - const char *intf = DBUS_INTERFACE_BLUEZ_DEVICE, *prop = "Alias"; - DBusMessage *msg, *reply; - DBusMessageIter reply_iter, variant_iter; - DBusError err; - - pa_assert(conn); - pa_assert(device_path); - pa_assert(name); - - if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_BLUEZ, device_path, "org.freedesktop.DBus.Properties", "Get"))) { - pa_log_error("dbus method call failed"); - return -1; - } - - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &intf, - DBUS_TYPE_STRING, &prop, - DBUS_TYPE_INVALID); - - dbus_error_init(&err); - if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) { - pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_BLUEZ_DEVICE, "Get", err.message); - dbus_error_free(&err); - return -1; - } - - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_VARIANT) { - pa_log_error("Cannot get reply argument"); - return -1; - } - - dbus_message_iter_recurse(&reply_iter, &variant_iter); - - if (dbus_message_iter_get_arg_type(&variant_iter) == DBUS_TYPE_STRING) { - dbus_message_iter_get_basic(&variant_iter, name); - } - - dbus_message_unref(reply); - return 0; -} - - -static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - DBusMessageIter msg_iter, array_iter, device_iter; - dm_device *device_item; - dm_device_profile *profile_item; - dm_device_state_t compound_state; - uint32_t device_idx; - dbus_int32_t device_id; - int mask_flags; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_log_debug("Get connected device list"); - - dm = (pa_device_manager*) userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &mask_flags, - DBUS_TYPE_INVALID)); - - dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiis)", &array_iter)); - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if(!(profile_item = pa_idxset_get_by_index(device_item->profiles, device_item->active_profile))) { - pa_log_error("no active profile"); - continue; - } - compound_state = COMPOUND_STATE(profile_item); - if (device_item_match_for_mask(device_item, mask_flags, dm)) { - device_id = (dbus_int32_t)device_item->id; - pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &profile_item->device_item->type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &profile_item->direction); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &compound_state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &device_item->name); - pa_assert_se(dbus_message_iter_close_container(&array_iter, &device_iter)); - } - } - - pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - - -static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dm_device *device_item; - dm_device_profile *profile_item; - dbus_bool_t is_bt_on = FALSE; - char *bt_name = "none"; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_log_debug("Get bt a2dp list"); - - dm = (pa_device_manager*) userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - if (!(device_item = _device_manager_get_device(dm->device_list, DEVICE_TYPE_BT))) { - if (!(profile_item = _device_item_get_profile(device_item, DEVICE_PROFILE_BT_A2DP))) { - is_bt_on = TRUE; - bt_name = device_item->name; - } - } - - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_bt_on, - DBUS_TYPE_STRING, &bt_name, - DBUS_TYPE_INVALID)); - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - - - -static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - char *device_type, *device_profile, *role; - DBusMessage *reply = NULL; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *) userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &device_type, - DBUS_TYPE_STRING, &device_profile, - DBUS_TYPE_STRING, &role, - DBUS_TYPE_INVALID)); - - if (pa_streq(device_profile, "none")) - device_profile = NULL; - pa_device_manager_load_sink(device_type, device_profile, role, dm); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm = (pa_device_manager *)userdata; - char *device_type, *device_profile; - dbus_int32_t status; - DBusMessage *reply = NULL; - DBusError error; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - dbus_error_init(&error); - if(!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &device_type, - DBUS_TYPE_STRING, &device_profile, - DBUS_TYPE_INT32, &status, - DBUS_TYPE_INVALID)) { - pa_log_error("failed to get dbus args : %s", error.message); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - } - - pa_log_debug("handle_test_device_status_change, type:%s, profile:%s, status:%d", device_type, device_profile, status); - if (pa_streq(device_profile, "none")) - device_profile = NULL; - - handle_device_status_changed(dm, device_type, device_profile, NULL, NULL, status); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *xml = DEVICE_MANAGER_INTROSPECT_XML; - DBusMessage *r = NULL; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se(r = dbus_message_new_method_return(msg)); - pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)); - - if (r) { - pa_assert_se(dbus_connection_send((conn), r, NULL)); - dbus_message_unref(r); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult handle_device_manager_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) { - int method_idx = 0; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - for (method_idx = 0; method_idx < METHOD_HANDLER_MAX; method_idx++) { - if (dbus_message_is_method_call(msg, DBUS_INTERFACE_DEVICE_MANAGER, method_handlers[method_idx].method_name )) { - method_handlers[method_idx].receive_cb(conn, msg, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult method_call_handler(DBusConnection *c, DBusMessage *m, void *userdata) { - struct userdata *u = userdata; - const char *path, *interface, *member; - - pa_assert(c); - pa_assert(m); - pa_assert(u); - - path = dbus_message_get_path(m); - interface = dbus_message_get_interface(m); - member = dbus_message_get_member(m); - - pa_log_debug("DeviceManager Method Call Handler : path=%s, interface=%s, member=%s", path, interface, member); - - if (!pa_streq(path, DBUS_OBJECT_DEVICE_MANAGER)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { - return handle_introspect(c, m, u); - /* - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Get")) { - return handle_get_property(c, m, u); - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set")) { - return handle_set_property(c, m, u); - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "GetAll")) { - return handle_get_all_property(c, m, u); - */ - } else { - return handle_device_manager_methods(c, m, u); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void endpoint_init(pa_device_manager *dm) { - static const DBusObjectPathVTable vtable_endpoint = { - .message_function = method_call_handler, - }; - - pa_log_debug("Device manager dbus endpoint init"); - - if (dm && dm->dbus_conn) { - if (!dbus_connection_register_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER, &vtable_endpoint, dm)) - pa_log_error("Failed to register object path"); - } else { - pa_log_error("Cannot get dbus connection to register object path"); - } -} - -static void endpoint_done(pa_device_manager *dm) { - pa_log_debug("Device manager dbus endpoint done"); - if (dm && dm->dbus_conn) { - if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER)) - pa_log_error("Failed to unregister object path"); - } else { - pa_log_error("Cannot get dbus connection to unregister object path"); - } -} - -static void dbus_init(pa_device_manager *dm) { - DBusError error; - pa_dbus_connection *connection = NULL; - - pa_assert(dm); - pa_log_debug("Dbus init"); - dbus_error_init(&error); - - if (!(connection = pa_dbus_bus_get(dm->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { - if (connection) { - pa_dbus_connection_unref(connection); - } - pa_log_error("Unable to contact D-Bus system bus: %s: %s", error.name, error.message); - goto fail; - } else { - pa_log_debug("Got dbus connection"); - } - - dm->dbus_conn = connection; - - if (watch_signals(dm) < 0) - pa_log_error("dbus watch signals failed"); - else - pa_log_debug("dbus ready to get signals"); - - endpoint_init(dm); - -fail: - dbus_error_free(&error); -} - -static void dbus_deinit(pa_device_manager *dm) { - pa_assert(dm); - - pa_log_debug("Dbus deinit"); - - endpoint_done(dm); - unwatch_signals(dm); - - if (dm->dbus_conn) { - pa_dbus_connection_unref(dm->dbus_conn); - dm->dbus_conn = NULL; - } -} -#endif - -pa_idxset* pa_device_manager_get_device_list(pa_device_manager *dm) { - pa_assert(dm); - pa_assert(dm->device_list); - - return dm->device_list; -} - -dm_device* pa_device_manager_get_device(pa_device_manager *dm, const char *device_type) { - pa_assert(dm); - - return _device_manager_get_device(dm->device_list, device_type); -} - -dm_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t id) { - pa_assert(dm); - - return _device_manager_get_device_with_id(dm->device_list, id); -} - -pa_sink* pa_device_manager_get_sink(dm_device *device_item, const char *role) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - if (!profile_item->playback_devices) { - pa_log_warn("No playback device in %s", device_item->name); - return NULL; - } - - return pa_hashmap_get(profile_item->playback_devices, role); -} - -pa_source* pa_device_manager_get_source(dm_device *device_item, const char *role) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - if (!profile_item->capture_devices) { - pa_log_warn("No capture device in %s", device_item->name); - return NULL; - } - - return pa_hashmap_get(profile_item->capture_devices, role); -} - -void pa_device_manager_set_device_state(dm_device *device_item, dm_device_direction_t direction, dm_device_state_t state) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - pa_log_debug("pa_device_manager_set_device_state : %s.%s direction %s -> %d", device_item->type, profile_item->profile, device_direction_to_string(direction), state); - _device_profile_set_state(profile_item, direction, state); -} - -dm_device_state_t pa_device_manager_get_device_state(dm_device *device_item, dm_device_direction_t direction) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - if (direction == DM_DEVICE_DIRECTION_BOTH) - return COMPOUND_STATE(profile_item); - else if (direction == DM_DEVICE_DIRECTION_OUT) - return profile_item->playback_state; - else if (direction == DM_DEVICE_DIRECTION_IN) - return profile_item->capture_state; - else - return DM_DEVICE_STATE_DEACTIVATED; -} - -uint32_t pa_device_manager_get_device_id(dm_device *device_item) { - pa_assert(device_item); - - return device_item->id; -} - -const char* pa_device_manager_get_device_type(dm_device *device_item) { - pa_assert(device_item); - - return device_item->type; -} - -const char* pa_device_manager_get_device_subtype(dm_device *device_item) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - return profile_item->profile; -} - -dm_device_direction_t pa_device_manager_get_device_direction(dm_device *device_item) { - dm_device_profile *profile_item; - - pa_assert(device_item); - pa_assert(profile_item = _device_item_get_active_profile(device_item)); - - return profile_item->direction; -} - -int pa_device_manager_bt_sco_open(pa_device_manager *dm) { - struct device_status_info *status_info; - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - if (!(status_info = _device_manager_get_status_info(dm->device_status, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, NULL))) { - pa_log_error("No status info for bt-sco"); - return -1; - } - if (!status_info->detected) { - pa_log_error("bt-sco not detected"); - return -1; - } - - pa_log_debug("bt sco open start"); - if (method_call_bt_sco(pa_dbus_connection_get(dm->dbus_conn), TRUE) < 0) { - pa_log_error("Failed to bt sco on"); - return -1; - } - - pa_log_debug("bt sco open end"); - - return 0; -} - -int pa_device_manager_bt_sco_close(pa_device_manager *dm) { - struct device_status_info *status_info; - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - if (!(status_info = _device_manager_get_status_info(dm->device_status, DEVICE_TYPE_BT, DEVICE_PROFILE_BT_SCO, NULL))) { - pa_log_error("No status info for bt-sco"); - return -1; - } - if (!status_info->detected) { - pa_log_error("bt-sco not detected"); - return -1; - } - - pa_log_debug("bt sco close start"); - if (method_call_bt_sco(pa_dbus_connection_get(dm->dbus_conn), FALSE) < 0) { - pa_log_error("Failed to bt sco close"); - return -1; - } - pa_log_debug("bt sco close end"); - - return 0; -} - -int pa_device_manager_bt_sco_get_property(pa_device_manager *dm, pa_bool_t *is_wide_band, pa_bool_t *nrec) { - pa_assert(dm); - pa_assert(dm->dbus_conn); - - pa_log_debug("bt sco get property start"); - - if (method_call_bt_sco_get_property(pa_dbus_connection_get(dm->dbus_conn), is_wide_band, nrec) < 0) { - pa_log_error("Failed to get bt property"); - return -1; - } - - pa_log_debug("bt sco get property end"); - - return 0; -} - -int pa_device_manager_load_sink(const char *device_type, const char *device_profile, const char *role, pa_device_manager *dm) { - const char *device_string, *params; - struct device_type_info *type_info; - struct device_file_info *file_info; - dm_device_profile *profile_item; - dm_device *device_item; - pa_sink *sink; - uint32_t device_idx; - - pa_assert(dm); - pa_assert(dm->device_list); - - pa_log_debug("load sink for '%s,%s'", device_type, role); - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if (pa_streq(device_type, device_item->type)) { - if ((profile_item = _device_item_get_profile(device_item, device_profile))) { - if (pa_hashmap_get(profile_item->playback_devices, role)) { - pa_log_warn("Proper sink for '%s:%s' already loaded", device_type, role); - return -1; - } - } - } - } - - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("No type map for %s", device_type); - return -1; - } - - if (!(device_string = pa_hashmap_get(type_info->playback_devices, role))) { - pa_log_error("No device-string for '%s:%s'", device_type, role); - goto failed; - } - - if (!(file_info = _device_manager_get_file_info(dm->file_map->playback, device_string))) { - pa_log_error("No playback file-map for '%s'", device_string); - goto failed; - } - - if (!(params = pa_hashmap_get(file_info->roles, role))) { - pa_log_error("No params for '%s,%s'", device_string, role); - goto failed; - } - - if ((sink = load_device(dm->core, PA_DEVICE_TYPE_SINK, device_string, params))) { - pa_log_debug("loaded sink '%s' for '%s,%s' success", sink->name, device_type, role); - } else { - pa_log_warn("Cannot load playback device with '%s,%s'", device_string, params); - goto failed; - } - - return 0; - -failed: - return -1; -} - -int pa_device_manager_load_source(const char *device_type, const char *device_profile, const char *role, pa_device_manager *dm) { - const char *device_string, *params; - struct device_type_info *type_info; - struct device_file_info *file_info; - dm_device_profile *profile_item; - dm_device *device_item; - pa_source *source; - uint32_t device_idx; - - pa_assert(dm); - - pa_log_debug("load source for '%s,%s'", device_type, role); - - PA_IDXSET_FOREACH(device_item, dm->device_list, device_idx) { - if (pa_streq(device_type, device_item->type)) { - if ((profile_item = _device_item_get_profile(device_item, device_profile))) { - if (pa_hashmap_get(profile_item->capture_devices, role)) { - pa_log_warn("Proper source for '%s:%s' already loaded", device_type, role); - return -1; - } - } - } - } - - - if (!(type_info = _device_manager_get_type_info(dm->type_infos, device_type, device_profile))) { - pa_log_error("No type map for %s", device_type); - return -1; - } - - if (!(device_string = pa_hashmap_get(type_info->capture_devices, role))) { - pa_log_error("No device-string for '%s:%s'", device_type, role); - goto failed; - } - - if (!(file_info = _device_manager_get_file_info(dm->file_map->capture, device_string))) { - pa_log_error("No capture file-map for '%s'", device_string); - goto failed; - } - - if (!(params = pa_hashmap_get(file_info->roles, role))) { - pa_log_error("No params for '%s,%s'", device_string, role); - goto failed; - } - - if ((source = load_device(dm->core, PA_DEVICE_TYPE_SOURCE, device_string, params))) { - pa_log_debug("loaded source '%s' for '%s,%s' success", source->name, device_type, role); - } else { - pa_log_warn("Cannot load capture device with '%s,%s'", device_string, params); - goto failed; - } - - return 0; - -failed: - return -1; -} - -pa_device_manager* pa_device_manager_init(pa_core *c) { - pa_device_manager *dm; - - pa_log_debug("pa_device_manager_init start"); - - dm = pa_xnew0(pa_device_manager, 1); - dm->core = c; - - dbus_init(dm); - - dm->sink_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, dm); - dm->sink_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, dm); - dm->source_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) source_put_hook_callback, dm); - dm->source_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) source_unlink_hook_callback, dm); - - dm->comm = pa_communicator_get(dm->core); - if (!(dm->type_infos = parse_device_type_infos())) { - pa_log_error("Parse device-type-map failed"); - return NULL; - } - - if (!(dm->file_map = parse_device_file_map())) { - pa_log_error("Parse device-file-map failed"); - return NULL; - } - - if (device_list_init(dm) < 0) { - pa_log_error("Init device list failed"); - return NULL; - } - - if (!(dm->device_status = device_type_status_init(dm->type_infos))) { - pa_log_error("Init device status failed"); - return NULL; - } - - if (load_builtin_devices(dm) != 0) { - pa_log_error("Load Builtin Devices faled"); - return NULL; - } - - /* Just for convenience when test*/ - if (!_device_manager_set_default_sink(dm, DEVICE_TYPE_SPEAKER, NULL, "normal")) { - pa_log_warn("Set default sink with speaker(normal) failed"); - } - if (!_device_manager_set_default_source(dm, DEVICE_TYPE_MIC, NULL, "normal")) { - pa_log_warn("Set default source with mic(normal) failed"); - } - - pa_log_debug("pa_device_manager_init end"); - - return dm; -} - -void pa_device_manager_done(pa_device_manager *dm) { - - if (!dm) - return; - - pa_log_debug("pa_device_manager_done start"); - - if (dm->sink_put_hook_slot) - pa_hook_slot_free(dm->sink_put_hook_slot); - if (dm->sink_unlink_hook_slot) - pa_hook_slot_free(dm->sink_unlink_hook_slot); - if (dm->source_put_hook_slot) - pa_hook_slot_free(dm->source_put_hook_slot); - if (dm->source_unlink_hook_slot) - pa_hook_slot_free(dm->source_unlink_hook_slot); - - if (dm->comm) - pa_communicator_unref(dm->comm); - - if (dm->type_infos) - pa_idxset_free(dm->type_infos, (pa_free_cb_t)type_info_free_func); - if (dm->file_map) { - if (dm->file_map->playback) - pa_idxset_free(dm->file_map->playback, (pa_free_cb_t)file_info_free_func); - if (dm->file_map->capture) - pa_idxset_free(dm->file_map->capture, (pa_free_cb_t)file_info_free_func); - pa_xfree(dm->file_map); - } - if (dm->device_list) - pa_idxset_free(dm->device_list, (pa_free_cb_t)device_item_free_func); - if (dm->device_status) - pa_idxset_free(dm->device_status, NULL); - - dbus_deinit(dm); - - pa_log_debug("pa_device_manager_done end"); -} diff --git a/src/modules/tizen/device-manager.h b/src/modules/tizen/device-manager.h deleted file mode 100644 index a62d701..0000000 --- a/src/modules/tizen/device-manager.h +++ /dev/null @@ -1,75 +0,0 @@ - -#include - -#define DEVICE_TYPE_SPEAKER "builtin-speaker" -#define DEVICE_TYPE_RECEIVER "builtin-receiver" -#define DEVICE_TYPE_MIC "builtin-mic" -#define DEVICE_TYPE_AUDIO_JACK "audio-jack" -#define DEVICE_TYPE_BT "bt" -#define DEVICE_TYPE_HDMI "hdmi" -#define DEVICE_TYPE_FORWARDING "forwarding" -#define DEVICE_TYPE_USB_AUDIO "usb-audio" -#define DEVICE_TYPE_NONE "none" - -#define DEVICE_PROFILE_BT_SCO "sco" -#define DEVICE_PROFILE_BT_A2DP "a2dp" - -#define DEVICE_ROLE_NORMAL "normal" -#define DEVICE_ROLE_VOIP "voip" -#define DEVICE_ROLE_LOW_LATENCY "low-latency" -#define DEVICE_ROLE_HIGH_LATENCY "high-latency" -#define DEVICE_ROLE_UHQA "uhqa" - -typedef enum dm_device_direction_type { - DM_DEVICE_DIRECTION_NONE, - DM_DEVICE_DIRECTION_IN = 0x1, - DM_DEVICE_DIRECTION_OUT = 0x2, - DM_DEVICE_DIRECTION_BOTH = DM_DEVICE_DIRECTION_IN | DM_DEVICE_DIRECTION_OUT -} dm_device_direction_t; - -typedef enum dm_device_changed_into_type { - DM_DEVICE_CHANGED_INFO_STATE, - DM_DEVICE_CHANGED_INFO_IO_DIRECTION, - DM_DEVICE_CHANGED_INFO_SUBTYPE, -} dm_device_changed_info_t; - -typedef enum dm_device_state_type { - DM_DEVICE_STATE_DEACTIVATED = 0, - DM_DEVICE_STATE_ACTIVATED -} dm_device_state_t; - -typedef struct pa_device_manager pa_device_manager; -typedef struct dm_device dm_device; - -typedef struct _hook_call_data_for_conn_changed { - pa_bool_t is_connected; - dm_device *device; -} pa_device_manager_hook_data_for_conn_changed; - -typedef struct _hook_call_data_for_info_changed { - dm_device_changed_info_t changed_info; - dm_device *device; -} pa_device_manager_hook_data_for_info_changed; - -pa_device_manager* pa_device_manager_init(pa_core* core); -void pa_device_manager_done(pa_device_manager *dm); - -pa_idxset* pa_device_manager_get_device_list(pa_device_manager *dm); -dm_device* pa_device_manager_get_device(pa_device_manager *dm, const char *device_type); -dm_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t id); - -pa_sink* pa_device_manager_get_sink(dm_device *device, const char *role); -pa_source* pa_device_manager_get_source(dm_device *device, const char *role); -void pa_device_manager_set_device_state(dm_device *device, dm_device_direction_t direction, dm_device_state_t state); -dm_device_state_t pa_device_manager_get_device_state(dm_device *device_item, dm_device_direction_t direction); -uint32_t pa_device_manager_get_device_id(dm_device *device); -const char* pa_device_manager_get_device_type(dm_device *device); -const char* pa_device_manager_get_device_subtype(dm_device *device); -dm_device_direction_t pa_device_manager_get_device_direction(dm_device *device); - -int pa_device_manager_load_sink(const char *device_type, const char *device_profile, const char *role, pa_device_manager *dm); -int pa_device_manager_load_source(const char *device_type, const char *device_profile, const char *role, pa_device_manager *dm); - -int pa_device_manager_bt_sco_open(pa_device_manager *dm); -int pa_device_manager_bt_sco_close(pa_device_manager *dm); -int pa_device_manager_bt_sco_get_property(pa_device_manager *dm, pa_bool_t *is_wide_band, pa_bool_t *nrec); diff --git a/src/modules/tizen/hal-manager.c b/src/modules/tizen/hal-manager.c deleted file mode 100644 index 25ec6c4..0000000 --- a/src/modules/tizen/hal-manager.c +++ /dev/null @@ -1,312 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2015 Sangchul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "hal-manager.h" -#include - -/* Audio HAL library */ -#define LIB_TIZEN_AUDIO "libtizen-audio.so" - -pa_hal_manager* pa_hal_manager_get(pa_core *core, void *user_data) { - pa_hal_manager *h; - - pa_assert(core); - - if ((h = pa_shared_get(core, "hal-manager"))) - return pa_hal_manager_ref(h); - - h = pa_xnew0(pa_hal_manager, 1); - PA_REFCNT_INIT(h); - h->core = core; - - /* Load library & init HAL manager */ - h->dl_handle = dlopen(LIB_TIZEN_AUDIO, RTLD_NOW); - if (h->dl_handle) { - h->intf.init = dlsym(h->dl_handle, "audio_init"); - h->intf.deinit = dlsym(h->dl_handle, "audio_deinit"); - h->intf.reset_volume = dlsym(h->dl_handle, "audio_reset_volume"); - h->intf.get_volume_level_max = dlsym(h->dl_handle, "audio_get_volume_level_max"); - h->intf.get_volume_level = dlsym(h->dl_handle, "audio_get_volume_level"); - h->intf.set_volume_level = dlsym(h->dl_handle, "audio_set_volume_level"); - h->intf.get_volume_value = dlsym(h->dl_handle, "audio_get_volume_value"); - h->intf.get_volume_mute = dlsym(h->dl_handle, "audio_get_volume_mute"); - h->intf.set_volume_mute = dlsym(h->dl_handle, "audio_set_volume_mute"); - h->intf.alsa_pcm_open = dlsym(h->dl_handle, "audio_alsa_pcm_open"); - h->intf.alsa_pcm_close = dlsym(h->dl_handle, "audio_alsa_pcm_close"); - h->intf.pcm_open = dlsym(h->dl_handle, "audio_pcm_open"); - h->intf.pcm_close = dlsym(h->dl_handle, "audio_pcm_close"); - h->intf.pcm_avail = dlsym(h->dl_handle, "audio_pcm_avail"); - h->intf.pcm_write = dlsym(h->dl_handle, "audio_pcm_write"); - h->intf.do_route = dlsym(h->dl_handle, "audio_do_route"); - h->intf.update_route_option = dlsym(h->dl_handle, "audio_update_route_option"); - h->intf.update_stream_connection_info = dlsym(h->dl_handle, "audio_update_stream_connection_info"); - h->intf.get_buffer_attr = dlsym(h->dl_handle, "audio_get_buffer_attr"); - if (h->intf.init) { - /* TODO : no need to pass platform_data as second param. need to fix hal. */ - if (h->intf.init(&h->data, user_data) != AUDIO_RET_OK) { - pa_log_error("hal_manager init failed"); - } - } -#if 1 /* remove comment after enable NEW_HAL */ - pa_shared_set(core, "tizen-audio-data", h->data); - pa_shared_set(core, "tizen-audio-interface", &h->intf); -#endif - - } else { - pa_log_error("open hal_manager failed :%s", dlerror()); - return NULL; - } - - pa_shared_set(core, "hal-manager", h); - - return h; -} - -pa_hal_manager* pa_hal_manager_ref(pa_hal_manager *h) { - pa_assert(h); - pa_assert(PA_REFCNT_VALUE(h) > 0); - - PA_REFCNT_INC(h); - - return h; -} - -void pa_hal_manager_unref(pa_hal_manager *h) { - pa_assert(h); - pa_assert(PA_REFCNT_VALUE(h) > 0); - - if (PA_REFCNT_DEC(h) > 0) - return; - - /* Deinit HAL manager & unload library */ - if (h->intf.deinit) { - if (h->intf.deinit(&h->data) != AUDIO_RET_OK) { - pa_log_error("hal_manager deinit failed"); - } - } - if (h->dl_handle) { - dlclose(h->dl_handle); - } - - if (h->core) - pa_shared_remove(h->core, "hal-manager"); - - pa_xfree(h); -} - -int32_t pa_hal_manager_get_buffer_attribute(pa_hal_manager *h, io_direction_t direction, const char *latency, void *new_data, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - pa_sample_spec *sample_spec = NULL; - - pa_assert(h); - pa_assert(new_data); - - sample_spec = (direction==DIRECTION_OUT)?(&((pa_sink_input_new_data*)new_data)->sample_spec):(&((pa_source_output_new_data*)new_data)->sample_spec); - pa_log_info("latency:%s, rate:%u, format:%d, channels:%u", latency, sample_spec->rate, sample_spec->format, sample_spec->channels); - - if (AUDIO_IS_ERROR(hal_ret = h->intf.get_buffer_attr(h->data, direction, latency, sample_spec->rate, sample_spec->format, sample_spec->channels, maxlength, tlength, prebuf, minreq, fragsize))) { - pa_log_error("get_buffer_attr returns error:0x%x", hal_ret); - ret = -1; - } else - pa_log_info("maxlength:%d, tlength:%d, prebuf:%d, minreq:%d, fragsize:%d", *maxlength, *tlength, *prebuf, *minreq, *fragsize); - - return ret; -} - -int32_t pa_hal_manager_reset_volume (pa_hal_manager *h) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - - pa_assert(h); - - if (AUDIO_IS_ERROR(hal_ret = h->intf.reset_volume(h->data))) { - pa_log_error("reset volume returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} - -int32_t pa_hal_manager_get_volume_level_max (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *level) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - audio_volume_info_t info = {NULL, NULL, 0}; - - pa_assert(h); - pa_assert(volume_type); - pa_assert(level); - - info.type = volume_type; - info.direction = direction; - - if (AUDIO_IS_ERROR((hal_ret = h->intf.get_volume_level_max(h->data, &info, level)))) { - pa_log_error("get_volume_level_max returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} - -int32_t pa_hal_manager_get_volume_level (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *level) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - audio_volume_info_t info = {NULL, NULL, 0}; - - pa_assert(h); - pa_assert(volume_type); - pa_assert(level); - - info.type = volume_type; - info.direction = direction; - - if (AUDIO_IS_ERROR((hal_ret = h->intf.get_volume_level(h->data, &info, level)))) { - pa_log_error("get_volume_level returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} - -int32_t pa_hal_manager_set_volume_level (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t level) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - audio_volume_info_t info = {NULL, NULL, 0}; - - pa_assert(h); - pa_assert(volume_type); - - info.type = volume_type; - info.direction = direction; - - if (AUDIO_IS_ERROR((hal_ret = h->intf.set_volume_level(h->data, &info, level)))) { - pa_log_error("set_volume_level returns error:0x%x", hal_ret); - ret = -1; - } - - return ret; -} - -int32_t pa_hal_manager_get_volume_value (pa_hal_manager *h, const char *volume_type, const char *gain_type, io_direction_t direction, uint32_t level, double *value) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - audio_volume_info_t info = {NULL, NULL, 0}; - - pa_assert(h); - pa_assert(volume_type); - pa_assert(value); - - info.type = volume_type; - info.gain = gain_type; - info.direction = direction; - - if (AUDIO_IS_ERROR((hal_ret = h->intf.get_volume_value(h->data, &info, level, value)))) { - pa_log_error("get_volume_value returns error:0x%x", hal_ret); - ret = -1; - } - - return ret; -} - -int32_t pa_hal_manager_get_mute (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *mute) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - audio_volume_info_t info = {NULL, NULL, 0}; - - pa_assert(h); - pa_assert(volume_type); - pa_assert(mute); - - info.type = volume_type; - info.direction = direction; - - if (AUDIO_IS_ERROR(hal_ret = h->intf.get_volume_mute(h->data, &info, mute))) { - pa_log_error("get_mute returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} - -int32_t pa_hal_manager_set_mute (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t mute) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - audio_volume_info_t info = {NULL, NULL, 0}; - - pa_assert(h); - pa_assert(volume_type); - - info.type = volume_type; - info.direction = direction; - - if (AUDIO_IS_ERROR(hal_ret = h->intf.set_volume_mute(h->data, &info, mute))) { - pa_log_error("set_mute returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} - -int32_t pa_hal_manager_do_route (pa_hal_manager *h, hal_route_info *info) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - - pa_assert(h); - pa_assert(info); - - if (AUDIO_IS_ERROR(hal_ret = h->intf.do_route(h->data, (audio_route_info_t*)info))) { - pa_log_error("do_route returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} - -int32_t pa_hal_manager_update_route_option (pa_hal_manager *h, hal_route_option *option) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - - pa_assert(h); - pa_assert(option); - - if (AUDIO_IS_ERROR(hal_ret = h->intf.update_route_option(h->data, (audio_route_option_t*)option))) { - pa_log_error("update_route_option returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} - -int32_t pa_hal_manager_update_stream_connection_info (pa_hal_manager *h, hal_stream_connection_info *info) { - int32_t ret = 0; - audio_return_t hal_ret = AUDIO_RET_OK; - audio_stream_info_t hal_info; - - pa_assert(h); - pa_assert(info); - - hal_info.role = info->role; - hal_info.direction = info->direction; - hal_info.idx = info->idx; - - if (AUDIO_IS_ERROR(hal_ret = h->intf.update_stream_connection_info(h->data, &hal_info, (uint32_t)info->is_connected))) { - pa_log_error("update_stream_connection_info returns error:0x%x", hal_ret); - ret = -1; - } - return ret; -} diff --git a/src/modules/tizen/hal-manager.h b/src/modules/tizen/hal-manager.h deleted file mode 100644 index d92c267..0000000 --- a/src/modules/tizen/hal-manager.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef foohalmanagerfoo -#define foohalmanagerfoo -#include -#include - -#include "tizen-audio.h" -/* TODO : move below structure to hal-manager.c */ -struct _pa_hal_manager { - PA_REFCNT_DECLARE; - - pa_core *core; - void *dl_handle; - void *data; - audio_interface_t intf; -}; - -typedef struct _pa_hal_manager pa_hal_manager; - -typedef enum _io_direction { - DIRECTION_IN, - DIRECTION_OUT, -} io_direction_t; - -typedef struct _hal_device_info { - const char *type; - uint32_t direction; - uint32_t id; -} hal_device_info; - -typedef struct _hal_route_info { - const char *role; - hal_device_info *device_infos; - uint32_t num_of_devices; -} hal_route_info; - -typedef struct _hal_route_option { - const char *role; - const char *name; - int32_t value; -} hal_route_option; - -typedef struct _hal_stream_connection_info { - const char *role; - uint32_t direction; - uint32_t idx; - pa_bool_t is_connected; -} hal_stream_connection_info; - -pa_hal_manager* pa_hal_manager_get(pa_core *core, void *user_data); -pa_hal_manager* pa_hal_manager_ref(pa_hal_manager *h); -void pa_hal_manager_unref(pa_hal_manager *h); -int32_t pa_hal_manager_get_buffer_attribute(pa_hal_manager *h, io_direction_t direction, const char *latency, void *new_data, uint32_t *maxlength, uint32_t *tlength, uint32_t *prebuf, uint32_t* minreq, uint32_t *fragsize); -int32_t pa_hal_manager_reset_volume (pa_hal_manager *h); -int32_t pa_hal_manager_get_volume_level_max (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *level); -int32_t pa_hal_manager_get_volume_level (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *level); -int32_t pa_hal_manager_set_volume_level (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t level); -int32_t pa_hal_manager_get_volume_value (pa_hal_manager *h, const char *volume_type, const char *gain_type, io_direction_t direction, uint32_t level, double *value); -int32_t pa_hal_manager_get_mute (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t *mute); -int32_t pa_hal_manager_set_mute (pa_hal_manager *h, const char *volume_type, io_direction_t direction, uint32_t mute); -int32_t pa_hal_manager_do_route (pa_hal_manager *h, hal_route_info *info); -int32_t pa_hal_manager_update_route_option (pa_hal_manager *h, hal_route_option *option); -int32_t pa_hal_manager_update_stream_connection_info (pa_hal_manager *h, hal_stream_connection_info *info); - -#endif diff --git a/src/modules/tizen/module-policy.c b/src/modules/tizen/module-policy.c deleted file mode 100644 index af44db5..0000000 --- a/src/modules/tizen/module-policy.c +++ /dev/null @@ -1,1544 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include // for mono -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_DBUS -#include -#include -#include -#endif - -#include "module-policy-symdef.h" -#include "communicator.h" -#include "hal-manager.h" -#include "stream-manager.h" -#include "stream-manager-volume.h" -#define DEVICE_MANAGER -#ifdef DEVICE_MANAGER -#include "device-manager.h" -#endif - -//To be changed -#ifndef VCONFKEY_SOUND_CAPTURE_STATUS -#define VCONFKEY_SOUND_CAPTURE_STATUS "memory/Sound/SoundCaptureStatus" -#endif - - -PA_MODULE_AUTHOR("Seungbae Shin"); -PA_MODULE_DESCRIPTION("Media Policy module"); -PA_MODULE_VERSION(PACKAGE_VERSION); -PA_MODULE_LOAD_ONCE(TRUE); -PA_MODULE_USAGE(" "); - -static const char* const valid_modargs[] = { - NULL -}; - -struct userdata; - -#ifdef HAVE_DBUS - -/*** Defines for module policy dbus interface ***/ -#define OBJECT_PATH "/org/pulseaudio/policy1" -#define INTERFACE_POLICY "org.PulseAudio.Ext.Policy1" -#define POLICY_INTROSPECT_XML \ - DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ - "" \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - "" - - -static DBusHandlerResult handle_get_property(DBusConnection *conn, DBusMessage *msg, void *userdata); -static DBusHandlerResult handle_get_all_property(DBusConnection *conn, DBusMessage *msg, void *userdata); -static DBusHandlerResult handle_set_property(DBusConnection *conn, DBusMessage *msg, void *userdata); -static DBusHandlerResult handle_policy_methods(DBusConnection *conn, DBusMessage *msg, void *userdata); -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata); -static DBusHandlerResult method_call_handler(DBusConnection *c, DBusMessage *m, void *userdata); -static void endpoint_init(struct userdata *u); -static void endpoint_done(struct userdata* u); - -/*** Called when module-policy load/unload ***/ -static void dbus_init(struct userdata* u); -static void dbus_deinit(struct userdata* u); - -/*** Defines for Property handle ***/ -/* property handlers */ -static void handle_get_property_test1(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_property_test1(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); -static void handle_get_property_test2(DBusConnection *conn, DBusMessage *msg, void *userdata); - -enum property_index { - PROPERTY_TEST1, - PROPERTY_TEST2, - PROPERTY_MAX -}; - -static pa_dbus_property_handler property_handlers[PROPERTY_MAX] = { - [PROPERTY_TEST1] = { .property_name = "PropertyTest1", .type = "i", - .get_cb = handle_get_property_test1, - .set_cb = handle_set_property_test1 }, - [PROPERTY_TEST2] = { .property_name = "PropertyTest2", .type = "s", - .get_cb = handle_get_property_test2, - .set_cb = NULL }, -}; - - -/*** Defines for method handle ***/ -/* method handlers */ -static void handle_method_test1(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_method_test2(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata); - -enum method_handler_index { - METHOD_HANDLER_TEST1, - METHOD_HANDLER_TEST2, - METHOD_HANDLER_MAX -}; - -static pa_dbus_arg_info method1_args[] = { { "arg1", "s", "in" }, - { "arg2", "u", "out" } }; - -static pa_dbus_arg_info method2_args[] = { { "arg1", "i", "in" }, - { "arg2", "i", "in" }, - { "arg3", "i", "out" } }; - -static const char* method_arg_signatures[] = { "s", "ii" }; - -static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { - [METHOD_HANDLER_TEST1] = { - .method_name = "MethodTest1", - .arguments = method1_args, - .n_arguments = sizeof(method1_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_method_test1 }, - [METHOD_HANDLER_TEST2] = { - .method_name = "MethodTest2", - .arguments = method2_args, - .n_arguments = sizeof(method2_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_method_test2 } -}; - -/*** Defines for signal send ***/ -static int watch_signals(struct userdata* u); -static void unwatch_signals(struct userdata* u); -static void send_prop1_changed_signal(struct userdata* u); - -enum signal_index { - SIGNAL_PROP_CHANGED, - SIGNAL_TEST2, - SIGNAL_MAX -}; - -/*** Defines for get signal ***/ -#define SOUND_SERVER_INTERFACE_NAME "org.tizen.soundserver.service" -#define AUDIO_CLIENT_INTERFACE_NAME "org.tizen.audioclient.service" - -#define SOUND_SERVER_FILTER \ - "type='signal'," \ - " interface='" SOUND_SERVER_INTERFACE_NAME "'" -#define AUDIO_CLIENT_FILTER \ - "type='signal'," \ - " interface='" AUDIO_CLIENT_INTERFACE_NAME "'" - -#endif - -/* Sink & Source names */ -#define SINK_COMBINED "sink_combined" -#define SINK_NULL "sink_null" -#define SOURCE_NULL "source_null" - -/* Policies */ -#define POLICY_HIGH_LATENCY "high-latency" -#define POLICY_HIGH_LATENCY_UHQA "high-latency-uhqa" - -/* Macros */ -#define CONVERT_TO_DEVICE_DIRECTION(stream_type) \ - ((stream_type==STREAM_SINK_INPUT)?DM_DEVICE_DIRECTION_OUT:DM_DEVICE_DIRECTION_IN) - -/* PCM Dump */ -#define PA_DUMP_INI_DEFAULT_PATH "/usr/etc/mmfw_audio_pcm_dump.ini" -#define PA_DUMP_INI_TEMP_PATH "/opt/system/mmfw_audio_pcm_dump.ini" -#define PA_DUMP_VCONF_KEY "memory/private/sound/pcm_dump" -#define PA_DUMP_PLAYBACK_DECODER_OUT 0x00000001 -#define PA_DUMP_PLAYBACK_RESAMPLER_IN 0x00000008 -#define PA_DUMP_PLAYBACK_RESAMPLER_OUT 0x00000010 -#define PA_DUMP_CAPTURE_ENCODER_IN 0x80000000 - -/* check if this sink is bluez */ - -struct pa_hal_device_event_data { - audio_device_info_t device_info; - audio_device_param_info_t params[AUDIO_DEVICE_PARAM_MAX]; -}; - -struct userdata { - pa_core *core; - pa_module *module; - - pa_native_protocol *protocol; - -#ifdef HAVE_DBUS - pa_dbus_connection *dbus_conn; - int32_t test_property1; -#endif - - struct { - pa_communicator *comm; - pa_hook_slot *comm_hook_select_proper_sink_or_source_slot; - pa_hook_slot *comm_hook_change_route_slot; - pa_hook_slot *comm_hook_update_route_option_slot; - pa_hook_slot *comm_hook_device_connection_changed_slot; - } communicator; - - pa_hal_manager *hal_manager; - pa_stream_manager *stream_manager; -#ifdef DEVICE_MANAGER - pa_device_manager *device_manager; -#endif - pa_module *module_combine_sink; - pa_module *module_null_sink; - pa_module *module_null_source; -}; - -enum { - SUBCOMMAND_TEST, - SUBCOMMAND_GET_VOLUME_LEVEL, - SUBCOMMAND_SET_VOLUME_LEVEL, - SUBCOMMAND_GET_MUTE, - SUBCOMMAND_SET_MUTE, -}; - -static int __convert_volume_type_to_string(uint32_t volume_type, const char **volume_type_str) { - int ret = 0; - switch (volume_type) { - case AUDIO_VOLUME_TYPE_SYSTEM: - *volume_type_str = "system"; - break; - case AUDIO_VOLUME_TYPE_NOTIFICATION: - *volume_type_str = "notification"; - break; - case AUDIO_VOLUME_TYPE_ALARM: - *volume_type_str = "alarm"; - break; - case AUDIO_VOLUME_TYPE_RINGTONE: - *volume_type_str = "ringtone"; - break; - case AUDIO_VOLUME_TYPE_MEDIA: - *volume_type_str = "media"; - break; - case AUDIO_VOLUME_TYPE_CALL: - *volume_type_str = "call"; - break; - case AUDIO_VOLUME_TYPE_VOIP: - *volume_type_str = "voip"; - break; - case AUDIO_VOLUME_TYPE_VOICE: - *volume_type_str = "voice"; - break; - case AUDIO_VOLUME_TYPE_FIXED: - *volume_type_str = "fixed"; - break; - default: - ret = -1; - } - pa_log_debug("volume_type[%d] => [%s], ret[%d]", volume_type, *volume_type_str, ret); - return ret; -} - -static void __load_dump_config(struct userdata *u) -{ - dictionary * dict = NULL; - int vconf_dump = 0; - - dict = iniparser_load(PA_DUMP_INI_DEFAULT_PATH); - if (!dict) { - pa_log_debug("%s load failed. Use temporary file", PA_DUMP_INI_DEFAULT_PATH); - dict = iniparser_load(PA_DUMP_INI_TEMP_PATH); - if (!dict) { - pa_log_warn("%s load failed", PA_DUMP_INI_TEMP_PATH); - return; - } - } - - vconf_dump |= iniparser_getboolean(dict, "pcm_dump:decoder_out", 0) ? PA_DUMP_PLAYBACK_DECODER_OUT : 0; - vconf_dump |= iniparser_getboolean(dict, "pcm_dump:resampler_in", 0) ? PA_DUMP_PLAYBACK_RESAMPLER_IN : 0; - vconf_dump |= iniparser_getboolean(dict, "pcm_dump:resampler_out", 0) ? PA_DUMP_PLAYBACK_RESAMPLER_OUT : 0; - vconf_dump |= iniparser_getboolean(dict, "pcm_dump:encoder_in", 0) ? PA_DUMP_CAPTURE_ENCODER_IN : 0; - u->core->dump_sink = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_sink", 0); - u->core->dump_sink_input = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_sink_input", 0); - u->core->dump_source = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_source", 0); - u->core->dump_source_output = (pa_bool_t)iniparser_getboolean(dict, "pcm_dump:pa_source_output", 0); - - iniparser_freedict(dict); - - if (vconf_set_int(PA_DUMP_VCONF_KEY, vconf_dump)) { - pa_log_warn("vconf_set_int %s=%x failed", PA_DUMP_VCONF_KEY, vconf_dump); - } -} - -#define EXT_VERSION 1 - -static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) { - struct userdata *u = NULL; - uint32_t command; - pa_tagstruct *reply = NULL; - - pa_assert(p); - pa_assert(m); - pa_assert(c); - pa_assert(t); - - u = m->userdata; - - if (pa_tagstruct_getu32(t, &command) < 0) - goto fail; - - reply = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(reply, PA_COMMAND_REPLY); - pa_tagstruct_putu32(reply, tag); - - switch (command) { - case SUBCOMMAND_TEST: { - if (!pa_tagstruct_eof(t)) - goto fail; - - pa_tagstruct_putu32(reply, EXT_VERSION); - break; - } - /* it will be removed soon */ - case SUBCOMMAND_GET_VOLUME_LEVEL: { - uint32_t stream_idx = PA_INVALID_INDEX; - uint32_t volume_type = 0; - uint32_t volume_level = 0; - const char *volume_str = NULL; - - pa_tagstruct_getu32(t, &stream_idx); - pa_tagstruct_getu32(t, &volume_type); - - __convert_volume_type_to_string(volume_type, &volume_str); - pa_stream_manager_volume_get_level(u->stream_manager, STREAM_SINK_INPUT, volume_str, &volume_level); - - pa_tagstruct_putu32(reply, volume_level); - break; - } - /* it will be removed soon */ - case SUBCOMMAND_SET_VOLUME_LEVEL: { - uint32_t stream_idx = PA_INVALID_INDEX; - uint32_t volume_type = 0; - uint32_t volume_level = 0; - const char *volume_str = NULL; - - pa_tagstruct_getu32(t, &stream_idx); - pa_tagstruct_getu32(t, &volume_type); - pa_tagstruct_getu32(t, &volume_level); - - __convert_volume_type_to_string(volume_type, &volume_str); - pa_stream_manager_volume_set_level(u->stream_manager, STREAM_SINK_INPUT, volume_str, volume_level); - break; - } - /* it will be removed soon */ - case SUBCOMMAND_GET_MUTE: { - uint32_t stream_idx = PA_INVALID_INDEX; - uint32_t volume_type = 0; - uint32_t direction = 0; - pa_bool_t mute = FALSE; - const char *volume_str = NULL; - - pa_tagstruct_getu32(t, &stream_idx); - pa_tagstruct_getu32(t, &volume_type); - pa_tagstruct_getu32(t, &direction); - - __convert_volume_type_to_string(volume_type, &volume_str); - pa_stream_manager_volume_get_mute(u->stream_manager, STREAM_SINK_INPUT, volume_str, &mute); - - pa_tagstruct_putu32(reply, (uint32_t)mute); - break; - } - /* it will be removed soon */ - case SUBCOMMAND_SET_MUTE: { - uint32_t stream_idx = PA_INVALID_INDEX; - uint32_t volume_type = 0; - uint32_t direction = 0; - uint32_t mute = 0; - const char *volume_str = NULL; - - pa_tagstruct_getu32(t, &stream_idx); - pa_tagstruct_getu32(t, &volume_type); - pa_tagstruct_getu32(t, &direction); - pa_tagstruct_getu32(t, &mute); - - __convert_volume_type_to_string(volume_type, &volume_str); - if ((int32_t)stream_idx == -1) - pa_stream_manager_volume_set_mute(u->stream_manager, STREAM_SINK_INPUT, volume_str, (pa_bool_t)mute); - else - pa_stream_manager_volume_set_mute_by_idx(u->stream_manager, STREAM_SINK_INPUT, stream_idx, (pa_bool_t)mute); - break; - } - - default: - goto fail; - } - - pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply); - return 0; - - fail: - - if (reply) - pa_tagstruct_free(reply); - - return -1; -} - -/* Set the proper sink(source) according to the data of the parameter. */ -/* - ROUTE_TYPE_AUTO(_ALL) */ -/* 1. Find the proper sink/source comparing between avail_devices */ -/* and current connected devices. */ -/* 2. If not found, set it to null sink/source. */ -/* - ROUTE_TYPE_MANUAL */ -/* 1. Find the proper sink/source comparing between avail_devices */ -/* and manual_devices that have been set by user. */ -/* 2. If not found, set it to null sink/source. */ -static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stream_manager_hook_data_for_select *data, struct userdata *u) { -#ifdef DEVICE_MANAGER - uint32_t idx = 0; - uint32_t m_idx = 0; - uint32_t conn_idx = 0; - uint32_t *device_id = NULL; - const char *device_type = NULL; - const char *dm_device_type = NULL; - const char *dm_device_subtype = NULL; - dm_device *device = NULL; - dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_NONE; - pa_idxset *conn_devices = NULL; - - pa_log_info("select_proper_sink_or_source_hook_cb is called. (%p), stream_type(%d), stream_role(%s), route_type(%d)", - data, data->stream_type, data->stream_role, data->route_type); - - if ((data->route_type == STREAM_ROUTE_TYPE_AUTO || data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL) && data->idx_avail_devices) { - /* Get current connected devices */ - conn_devices = pa_device_manager_get_device_list(u->device_manager); - PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_debug("[AUTO(_ALL)] avail_device[%u] for this role[%s]: type(%s)", idx, data->stream_role, device_type); - PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - device_direction = pa_device_manager_get_device_direction(device); - pa_log_debug("[AUTO(_ALL)] conn_devices, type[%s], subtype[%s], direction[0x%x]", dm_device_type, dm_device_subtype, device_direction); - if (pa_streq(device_type, dm_device_type) && - (((data->stream_type==STREAM_SINK_INPUT) && (device_direction & DM_DEVICE_DIRECTION_OUT)) || - ((data->stream_type==STREAM_SOURCE_OUTPUT) && (device_direction & DM_DEVICE_DIRECTION_IN)))) { - pa_log_debug("[AUTO(_ALL)] found a matched device: type[%s], direction[0x%x]", device_type, device_direction); - - if (data->stream_type == STREAM_SINK_INPUT && u->module_combine_sink) { - *(data->proper_sink) = pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK); - pa_log_debug("[AUTO(_ALL)] found the combine-sink, set it to the sink"); - } else if (data->stream_type == STREAM_SINK_INPUT) - *(data->proper_sink) = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - else - *(data->proper_source) = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); - goto SUCCESS; - } - } - } - /* need to add logic for auto-all. (use combine-sink, move sink-input/source-output) */ - - } else if (data->route_type == STREAM_ROUTE_TYPE_MANUAL && data->idx_manual_devices && data->idx_avail_devices) { - PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_debug("[MANUAL] avail_device[%u] for this role[%s]: type(%s)", idx, data->stream_role, device_type); - PA_IDXSET_FOREACH(device_id, data->idx_manual_devices, m_idx) { - device = pa_device_manager_get_device_by_id(u->device_manager, *device_id); - if (device) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - device_direction = pa_device_manager_get_device_direction(device); - pa_log_debug("[MANUAL] manual_devices, type[%s], subtype[%s], direction[0x%x], device id[%u]", - dm_device_type, dm_device_subtype, device_direction, *device_id); - if (pa_streq(device_type, dm_device_type) && - (((data->stream_type==STREAM_SINK_INPUT) && (device_direction & DM_DEVICE_DIRECTION_OUT)) || - ((data->stream_type==STREAM_SOURCE_OUTPUT) && (device_direction & DM_DEVICE_DIRECTION_IN)))) { - pa_log_debug("[MANUAL] found a matched device: type[%s], direction[0x%x]", device_type, device_direction); - if (data->stream_type == STREAM_SINK_INPUT) - *(data->proper_sink) = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - else - *(data->proper_source) = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); - goto SUCCESS; - } - } - } - } - } - - if ((data->stream_type==STREAM_SINK_INPUT)?!(*(data->proper_sink)):!(*(data->proper_source))) { - pa_log_warn("could not find a proper sink/source, set it to null sink/source"); - if (data->stream_type == STREAM_SINK_INPUT) - *(data->proper_sink) = (pa_sink*)pa_namereg_get(u->core, SINK_NULL, PA_NAMEREG_SINK); - else - *(data->proper_source) = (pa_source*)pa_namereg_get(u->core, SOURCE_NULL, PA_NAMEREG_SOURCE); - } -SUCCESS: -#endif - return PA_HOOK_OK; -} - -/* Change the route setting according to the data from argument. */ -/* This function is called only when it needs to change routing path via HAL. */ -/* - role is "reset" */ -/* 1. It will be received when it is needed to terminate playback */ -/* or capture routing path. */ -/* 2. Update the state of the device to be deactivated. */ -/* 3. Call HAL API to reset routing. */ -/* - ROUTE_TYPE_AUTO */ -/* 1. Find the proper sink/source comparing between avail_devices */ -/* and current connected devices. */ -/* : Need to check the priority of the device list by order of receipt. */ -/* 2. Update the state of devices. */ -/* 3. Call HAL API to apply the routing setting */ -/* - ROUTE_TYPE_AUTO_ALL */ -/* 1. Find the proper sink/source comparing between avail_devices */ -/* and current connected devices. */ -/* : Might use combine-sink according to the conditions. */ -/* 2. Update the state of devices. */ -/* 3. Call HAL API to apply the routing setting */ -/* - ROUTE_TYPE_MANUAL */ -/* 1. Find the proper sink/source comparing between avail_devices */ -/* and manual_devices that have been set by user. */ -/* 2. Update the state of devices. */ -/* 3. Call HAL API to apply the routing setting */ -static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_data_for_route *data, struct userdata *u) { -#ifdef DEVICE_MANAGER - uint32_t i = 0; - uint32_t idx = 0; - uint32_t d_idx = 0; - uint32_t s_idx = 0; - uint32_t *stream_idx = NULL; - hal_route_info route_info = {NULL, NULL, 0}; - uint32_t conn_idx = 0; - uint32_t *device_id = NULL; - uint32_t device_idx = 0; - const char *device_type = NULL; - dm_device *device = NULL; - dm_device *_device = NULL; - const char *dm_device_type = NULL; - const char *dm_device_subtype = NULL; - dm_device_state_t device_state = DM_DEVICE_STATE_DEACTIVATED; - dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_NONE; - void *s = NULL; - pa_sink *sink = NULL; - pa_source *source = NULL; - pa_idxset *conn_devices = NULL; - pa_sink *combine_sink_arg1 = NULL; - pa_sink *combine_sink_arg2 = NULL; - char *args = NULL; - - pa_log_info("route_change_hook_cb is called. (%p), stream_type(%d), stream_role(%s), route_type(%d)", - data, data->stream_type, data->stream_role, data->route_type); - route_info.role = data->stream_role; - - /* Streams */ - if (data->idx_streams) { - PA_IDXSET_FOREACH(stream_idx, data->idx_streams, idx) { - pa_log_debug("-- stream[%u]: idx(%u)", idx, *stream_idx); - } - } - - /* Devices */ - if (pa_streq(data->stream_role, "reset")) { - /* Get current connected devices */ - conn_devices = pa_device_manager_get_device_list(u->device_manager); - /* Set device state to deactivate */ - PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - device_state = pa_device_manager_get_device_state(device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type)); - device_direction = pa_device_manager_get_device_direction(device); - if (device_state == DM_DEVICE_STATE_ACTIVATED && - (((data->stream_type==STREAM_SINK_INPUT) && (device_direction & DM_DEVICE_DIRECTION_OUT)) || - ((data->stream_type==STREAM_SOURCE_OUTPUT) && (device_direction & DM_DEVICE_DIRECTION_IN)))) { - pa_log_debug("[RESET] found a matched device and set state to DE-ACTIVATED: type[%s], direction[0x%x]", dm_device_type, device_direction); - /* set device state to deactivated */ - pa_device_manager_set_device_state(device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type), DM_DEVICE_STATE_DEACTIVATED); - } - } - route_info.num_of_devices = 1; - route_info.device_infos = pa_xmalloc0(sizeof(hal_device_info)*route_info.num_of_devices); - route_info.device_infos[0].direction = (data->stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN; - - /* unload combine sink */ - if (data->stream_type==STREAM_SINK_INPUT && u->module_combine_sink) { - pa_log_debug ("[RESET] unload module[%s]", SINK_COMBINED); - pa_sink_suspend(pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK), TRUE, PA_SUSPEND_USER); - pa_module_unload(u->module->core, u->module_combine_sink, TRUE); - u->module_combine_sink = NULL; - } - - } else if ((data->route_type == STREAM_ROUTE_TYPE_AUTO || data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL) && data->idx_avail_devices) { - /* Get current connected devices */ - conn_devices = pa_device_manager_get_device_list(u->device_manager); - PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_debug("[AUTO(_ALL)] avail_device[%u] for this role[%s]: type[%s]", idx, route_info.role, device_type); - PA_IDXSET_FOREACH(device, conn_devices, conn_idx) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - device_direction = pa_device_manager_get_device_direction(device); - device_idx = pa_device_manager_get_device_id(device); - pa_log_debug("[AUTO(_ALL)] conn_devices, type[%s], subtype[%s], direction[0x%x], id[%u]", - dm_device_type, dm_device_subtype, device_direction, device_idx); - if (pa_streq(device_type, dm_device_type) && - (((data->stream_type==STREAM_SINK_INPUT) && (device_direction & DM_DEVICE_DIRECTION_OUT)) || - ((data->stream_type==STREAM_SOURCE_OUTPUT) && (device_direction & DM_DEVICE_DIRECTION_IN)))) { - if (dm_device_subtype && pa_streq(DEVICE_PROFILE_BT_SCO, dm_device_subtype)) - continue; - route_info.num_of_devices++; - route_info.device_infos = pa_xrealloc(route_info.device_infos, sizeof(hal_device_info)*route_info.num_of_devices); - route_info.device_infos[route_info.num_of_devices-1].type = dm_device_type; - route_info.device_infos[route_info.num_of_devices-1].direction = (data->stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN; - route_info.device_infos[route_info.num_of_devices-1].id = device_idx; - pa_log_debug("[AUTO(_ALL)] found a matched device and set state to ACTIVATED: type[%s], direction[0x%x], id[%u]", - route_info.device_infos[route_info.num_of_devices-1].type, device_direction, device_idx); - /* Set device state to activated */ - pa_device_manager_set_device_state(device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type), DM_DEVICE_STATE_ACTIVATED); - break; - } - } - if (data->route_type == STREAM_ROUTE_TYPE_AUTO && device) { - /* Set other device's state to deactivated */ - PA_IDXSET_FOREACH(_device, conn_devices, conn_idx) { - if (device == _device) - continue; - pa_device_manager_set_device_state(_device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type), DM_DEVICE_STATE_DEACTIVATED); - } - - /* Move sink-inputs/source-outputs if needed */ - if (data->stream_type == STREAM_SINK_INPUT) - sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - else if (data->stream_type == STREAM_SOURCE_OUTPUT) - source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); - if (data->idx_streams) { - PA_IDXSET_FOREACH (s, data->idx_streams, s_idx) { - if (sink && (sink != ((pa_sink_input*)s)->sink)) { - pa_sink_input_move_to(s, sink, FALSE); - pa_log_debug("[AUTO] *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, sink, sink->name); - } else if (source && (source != ((pa_source_output*)s)->source)) { - pa_source_output_move_to(s, source, FALSE); - pa_log_debug("[AUTO] *** source-output(%p,%u) moves to source(%p,%s)", s, ((pa_source_output*)s)->index, source, source->name); - } - } - } - /* unload combine sink */ - if (data->stream_type==STREAM_SINK_INPUT && u->module_combine_sink) { - pa_sink *combine_sink = pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK); - if (combine_sink->inputs) { - PA_IDXSET_FOREACH (s, combine_sink->inputs, s_idx) { - pa_sink_input_move_to(s, sink, FALSE); - pa_log_debug("[AUTO] *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, sink, sink->name); - } - } - pa_log_debug ("[AUTO] unload module[%s]", SINK_COMBINED); - pa_sink_suspend(pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK), TRUE, PA_SUSPEND_USER); - pa_module_unload(u->module->core, u->module_combine_sink, TRUE); - u->module_combine_sink = NULL; - } - break; - - } else if (data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL && device) { - /* find the proper sink/source */ - /* currently, we support two sinks for combining */ - if (data->stream_type == STREAM_SINK_INPUT && u->module_combine_sink) { - sink = pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK); - pa_log_debug ("[AUTO_ALL] found the combine_sink already existed"); - } else if (data->stream_type == STREAM_SINK_INPUT && !combine_sink_arg1) { - sink = combine_sink_arg1 = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - pa_log_debug ("[AUTO_ALL] combine_sink_arg1[%s], combine_sink_arg2[%p]", sink->name, combine_sink_arg2); - } else if (data->stream_type == STREAM_SINK_INPUT && !combine_sink_arg2) { - sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - if(sink && !pa_streq(sink->name, combine_sink_arg1->name)) { - pa_log_debug ("[AUTO_ALL] combine_sink_arg2[%s]", sink->name); - combine_sink_arg2 = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - /* load combine sink */ - if (!u->module_combine_sink) { - args = pa_sprintf_malloc("sink_name=%s slaves=\"%s,%s\"", SINK_COMBINED, combine_sink_arg1->name, combine_sink_arg2->name); - pa_log_debug ("[AUTO_ALL] combined sink is not prepared, now load module[%s]", args); - u->module_combine_sink = pa_module_load(u->module->core, "module-combine-sink", args); - pa_xfree(args); - } - sink = pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK); - PA_IDXSET_FOREACH (s, combine_sink_arg1->inputs, s_idx) { - pa_sink_input_move_to(s, sink, FALSE); - pa_log_debug("[AUTO_ALL] *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, sink, sink->name); - } - } - } else if (data->stream_type == STREAM_SOURCE_OUTPUT) { - source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); - } - - if (data->origins_from_new_data) { - if (data->stream_type == STREAM_SINK_INPUT) - *(data->proper_sink) = sink; - else - *(data->proper_source) = source; - } else { - /* Move sink-inputs/source-outputs if needed */ - if (data->idx_streams) { - PA_IDXSET_FOREACH (s, data->idx_streams, s_idx) { - if (sink && (sink != ((pa_sink_input*)s)->sink)) { - pa_sink_input_move_to(s, sink, FALSE); - pa_log_debug("[AUTO(_ALL)] *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, sink, sink->name); - } else if (source && (source != ((pa_source_output*)s)->source)) { - pa_source_output_move_to(s, source, FALSE); - pa_log_debug("[AUTO(_ALL)] *** source-output(%p,%u) moves to source(%p,%s)", s, ((pa_source_output*)s)->index, source, source->name); - } - } - } - if (u->module_null_sink) { - pa_sink *null_sink = pa_namereg_get(u->module->core, SINK_NULL, PA_NAMEREG_SINK); - if (null_sink) { - PA_IDXSET_FOREACH (s, null_sink->inputs, s_idx) { - pa_sink_input_move_to(s, sink, FALSE); - pa_log_debug("[AUTO(_ALL)] *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, sink, sink->name); - } - } - } - } - } - } - - if (data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL && route_info.num_of_devices) { - /* Set other device's state to deactivated */ - PA_IDXSET_FOREACH(_device, conn_devices, conn_idx) { - pa_bool_t need_to_deactive = TRUE; - device_idx = pa_device_manager_get_device_id(_device); - for (i = 0; i < route_info.num_of_devices; i++) { - if (device_idx == route_info.device_infos[i].id) { - need_to_deactive = FALSE; - break; - } - } - if (need_to_deactive) - pa_device_manager_set_device_state(_device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type), DM_DEVICE_STATE_DEACTIVATED); - } - } - - } else if (data->route_type == STREAM_ROUTE_TYPE_MANUAL && data->idx_manual_devices && data->idx_avail_devices) { - PA_IDXSET_FOREACH(device_type, data->idx_avail_devices, idx) { - pa_log_debug("[MANUAL] avail_device[%u] for this role[%s]: type(%s)", idx, data->stream_role, device_type); - PA_IDXSET_FOREACH(device_id, data->idx_manual_devices, d_idx) { - pa_log_debug("[MANUAL] manual_device[%u] for this role[%s]: device_id(%u)", idx, data->stream_role, *device_id); - device = pa_device_manager_get_device_by_id(u->device_manager, *device_id); - if (device) { - dm_device_type = pa_device_manager_get_device_type(device); - dm_device_subtype = pa_device_manager_get_device_subtype(device); - device_direction = pa_device_manager_get_device_direction(device); - pa_log_debug("[MANUAL] manual_device, type[%s], subtype[%s], direction[0x%x]", dm_device_type, dm_device_subtype, device_direction); - if (pa_streq(device_type, dm_device_type) && - (((data->stream_type==STREAM_SINK_INPUT) && (device_direction & DM_DEVICE_DIRECTION_OUT)) || - ((data->stream_type==STREAM_SOURCE_OUTPUT) && (device_direction & DM_DEVICE_DIRECTION_IN)))) { - pa_log_debug("[MANUAL] found a matched device: type[%s], direction[0x%x]", device_type, device_direction); - route_info.num_of_devices++; - route_info.device_infos = pa_xrealloc(route_info.device_infos, sizeof(hal_device_info)*route_info.num_of_devices); - route_info.device_infos[route_info.num_of_devices-1].type = dm_device_type; - route_info.device_infos[route_info.num_of_devices-1].direction = (data->stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN; - pa_log_debug("[MANUAL] found a matched device and set state to ACTIVATED: type[%s], direction[0x%x]", - route_info.device_infos[route_info.num_of_devices-1].type, device_direction); - /* Set device state to activated */ - pa_device_manager_set_device_state(device, CONVERT_TO_DEVICE_DIRECTION(data->stream_type), DM_DEVICE_STATE_ACTIVATED); - } - } - } - } - - /* Move sink-inputs/source-outputs if needed */ - if (device && !data->origins_from_new_data) { - if (data->stream_type == STREAM_SINK_INPUT) - sink = pa_device_manager_get_sink(device, DEVICE_ROLE_NORMAL); - else if (data->stream_type == STREAM_SOURCE_OUTPUT) - source = pa_device_manager_get_source(device, DEVICE_ROLE_NORMAL); - if (data->idx_streams) { - PA_IDXSET_FOREACH (s, data->idx_streams, idx) { - if (sink && (sink != ((pa_sink_input*)s)->sink)) { - pa_sink_input_move_to(s, sink, FALSE); - pa_log_debug("[MANUAL] *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, sink, sink->name); - } else if (source && (source != ((pa_source_output*)s)->source)) { - pa_source_output_move_to(s, source, FALSE); - pa_log_debug("[MANUAL] *** source-output(%p,%u) moves to source(%p,%s)", s, ((pa_source_output*)s)->index, source, source->name); - } - } - } - } - } - - if (route_info.device_infos) { - /* Send information to HAL to set routing */ - if(pa_hal_manager_do_route (u->hal_manager, &route_info)) - pa_log_error("Failed to pa_hal_manager_do_route()"); - pa_xfree(route_info.device_infos); - } -#endif - return PA_HOOK_OK; -} - -/* Forward routing option to HAL */ -static pa_hook_result_t route_option_update_hook_cb(pa_core *c, pa_stream_manager_hook_data_for_option *data, struct userdata *u) { - hal_route_option route_option; - - pa_log_info("route_option_update_hook_cb is called. (%p), stream_role(%s), option[name(%s)/value(%d)]", - data, data->stream_role, data->name, data->value); - route_option.role = data->stream_role; - route_option.name = data->name; - route_option.value = data->value; - - /* Send information to HAL to update routing option */ - if(pa_hal_manager_update_route_option (u->hal_manager, &route_option)) - pa_log_error("Failed to pa_hal_manager_update_route_option()"); - - return PA_HOOK_OK; -} - -/* Reorganize routing when a device has been connected or disconnected */ -static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *conn, struct userdata *u) { - uint32_t s_idx = 0; - pa_sink_input *s = NULL; - const char *device_type = NULL; - const char *device_subtype = NULL; - dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT; - - device_direction = pa_device_manager_get_device_direction(conn->device); - device_type = pa_device_manager_get_device_type(conn->device); - device_subtype = pa_device_manager_get_device_subtype(conn->device); - pa_log_info("device_connection_changed_hook_cb is called. conn(%p), is_connected(%d), device(%p,%s,%s), direction(0x%x)", - conn, conn->is_connected, conn->device, device_type, device_subtype, device_direction); - - if (!conn->is_connected && pa_streq(DEVICE_TYPE_BT, device_type) && - device_subtype && pa_streq(DEVICE_PROFILE_BT_A2DP, device_subtype) && - device_direction == DM_DEVICE_DIRECTION_OUT) { - if (u->module_combine_sink) { - /* unload combine sink */ - pa_sink *combine_sink = pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK); - pa_sink *null_sink = pa_namereg_get(u->module->core, SINK_NULL, PA_NAMEREG_SINK); - if (combine_sink->inputs) { - PA_IDXSET_FOREACH (s, combine_sink->inputs, s_idx) { - pa_sink_input_move_to(s, null_sink, FALSE); - pa_log_debug(" *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, null_sink, null_sink->name); - } - } - pa_sink_suspend(pa_namereg_get(u->module->core, SINK_COMBINED, PA_NAMEREG_SINK), TRUE, PA_SUSPEND_USER); - pa_module_unload(u->module->core, u->module_combine_sink, TRUE); - u->module_combine_sink = NULL; - } - } - - return PA_HOOK_OK; -} - -#ifdef HAVE_DBUS -static void _do_something1(char* arg1, int arg2, void *data) -{ - pa_assert(data); - pa_assert(arg1); - - pa_log_debug("Do Something 1 , arg1 (%s) arg2 (%d)", arg1, arg2); -} - -static void _do_something2(char* arg1, void *data) -{ - pa_assert(data); - pa_assert(arg1); - - pa_log_debug("Do Something 2 , arg1 (%s) ", arg1); -} - -static void handle_get_property_test1(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - struct userdata *u = userdata; - dbus_int32_t value_i = 0; - - pa_assert(conn); - pa_assert(msg); - pa_assert(u); - - value_i = u->test_property1; - - pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_INT32, &value_i); -} - -static void handle_set_property_test1(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) -{ - struct userdata *u = userdata; - dbus_int32_t value_i = 0; - pa_assert(conn); - pa_assert(msg); - pa_assert(u); - - dbus_message_iter_get_basic(iter, &value_i); - - u->test_property1 = value_i; - pa_dbus_send_empty_reply(conn, msg); - - /* send signal to notify change of property1*/ - send_prop1_changed_signal(u); -} - -/* test property handler : return module name */ -static void handle_get_property_test2(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - struct userdata *u = userdata; - pa_assert(conn); - pa_assert(msg); - pa_assert(u); - - if (!u->module->name) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "property(module name) null"); - return; - } - - pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_STRING, &u->module->name); -} - -static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - struct userdata *u = userdata; - dbus_int32_t value_i = 0; - - DBusMessage *reply = NULL; - DBusMessageIter msg_iter; - DBusMessageIter dict_iter; - - pa_assert(conn); - pa_assert(msg); - pa_assert(u); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - value_i = u->test_property1; - - dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter)); - - pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_TEST1].property_name, DBUS_TYPE_INT32, &value_i); - pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_TEST2].property_name, DBUS_TYPE_STRING, &u->module->name); - pa_assert_se(dbus_message_iter_close_container(&msg_iter, &dict_iter)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -/* test method : return length of argument string */ -static void handle_method_test1(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - const char* arg1_s = NULL; - dbus_uint32_t value_u = 0; - pa_assert(conn); - pa_assert(msg); - - pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &arg1_s, DBUS_TYPE_INVALID)); - value_u = strlen(arg1_s); - pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_UINT32, &value_u); -} - -static void handle_method_test2(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - dbus_int32_t value1, value2, result; - pa_assert(conn); - pa_assert(msg); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &value1, - DBUS_TYPE_INT32, &value2, - DBUS_TYPE_INVALID)); - - result = value1 * value2; - - pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_INT32, &result); -} - -static DBusMessage* _generate_basic_property_change_signal_msg(int property_index, int property_type, void *data) { - DBusMessage *signal_msg; - DBusMessageIter signal_iter, dict_iter; - const char *interface = INTERFACE_POLICY; - - /* org.freedesktop.DBus.Properties.PropertiesChanged ( - STRING interface_name, - DICT changed_properties, - ARRAY invalidated_properties); */ - - pa_assert_se(signal_msg = dbus_message_new_signal(OBJECT_PATH, DBUS_INTERFACE_PROPERTIES, SIGNAL_PROP_CHANGED)); - dbus_message_iter_init_append(signal_msg, &signal_iter); - - /* STRING interface_name */ - dbus_message_iter_append_basic(&signal_iter, DBUS_TYPE_STRING, &interface); - - /* DICT changed_properties */ - pa_assert_se(dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY, "{sv}", &dict_iter)); - pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[property_index].property_name, - property_type, data); - dbus_message_iter_close_container(&signal_iter, &dict_iter); - - /* ARRAY invalidated_properties (empty) */ - dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY, "s", &dict_iter); - dbus_message_iter_close_container(&signal_iter, &dict_iter); - - return signal_msg; -} - -static void send_prop1_changed_signal(struct userdata* u) { - DBusMessage *signal_msg = _generate_basic_property_change_signal_msg(PROPERTY_TEST1, DBUS_TYPE_INT32, &u->test_property1); - -#ifdef USE_DBUS_PROTOCOL - pa_dbus_protocol_send_signal(u->dbus_protocol, signal_msg); -#else - dbus_connection_send(pa_dbus_connection_get(u->dbus_conn), signal_msg, NULL); -#endif - - dbus_message_unref(signal_msg); -} - -static DBusHandlerResult dbus_filter_audio_handler(DBusConnection *c, DBusMessage *s, void *userdata) -{ - DBusError error; - char* arg_s = NULL; - int arg_i = 0; - - pa_assert(userdata); - - if(dbus_message_get_type(s)!=DBUS_MESSAGE_TYPE_SIGNAL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - pa_log_info("Audio handler received msg"); - dbus_error_init(&error); - - if (dbus_message_is_signal(s, SOUND_SERVER_INTERFACE_NAME, "TestSignalFromSS1")) { - if (!dbus_message_get_args(s, NULL, - DBUS_TYPE_STRING, &arg_s, - DBUS_TYPE_INT32, &arg_i , - DBUS_TYPE_INVALID)) { - goto fail; - } else { - _do_something1(arg_s, arg_i, userdata); - } - } else if (dbus_message_is_signal(s, SOUND_SERVER_INTERFACE_NAME, "TestSignalFromSS2")) { - if (!dbus_message_get_args(s, NULL, - DBUS_TYPE_STRING, &arg_s, - DBUS_TYPE_INVALID)) { - goto fail; - } else{ - _do_something2(arg_s, userdata); - } - } else if (dbus_message_is_signal(s, AUDIO_CLIENT_INTERFACE_NAME, "TestSignalFromClient1")) { - if (!dbus_message_get_args(s, NULL, - DBUS_TYPE_STRING, &arg_s, - DBUS_TYPE_INVALID)) { - goto fail; - } else{ - _do_something2(arg_s, userdata); - } - } else { - pa_log_info("Unknown message, not handle it"); - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - pa_log_debug("Dbus Message handled"); - - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_HANDLED; - -fail: - pa_log_error("Fail to handle dbus signal"); - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult handle_get_property(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - int prop_idx = 0; - const char *interface_name, *property_name; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - if (pa_streq(dbus_message_get_signature(msg), "ss")) { - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &interface_name, - DBUS_TYPE_STRING, &property_name, - DBUS_TYPE_INVALID)); - if (pa_streq(interface_name, INTERFACE_POLICY)) { - for (prop_idx = 0; prop_idx < PROPERTY_MAX; prop_idx++) { - if (pa_streq(property_name, property_handlers[prop_idx].property_name)) { - property_handlers[prop_idx].get_cb(conn, msg, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } - } - } - else{ - pa_log_warn("Not our interface, not handle it"); - } - } else{ - pa_log_warn("Wrong Signature"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_SIGNATURE, "Wrong Signature, Expected (ss)"); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult handle_get_all_property(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - const char *interface_name; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - if (pa_streq(dbus_message_get_signature(msg), "s")) { - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &interface_name, - DBUS_TYPE_INVALID)); - if (pa_streq(interface_name, INTERFACE_POLICY)) { - handle_get_all(conn, msg, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } - else{ - pa_log_warn("Not our interface, not handle it"); - } - } else{ - pa_log_warn("Wrong Signature"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_SIGNATURE, "Wrong Signature, Expected (ss)"); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult handle_set_property(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - int prop_idx = 0; - const char *interface_name, *property_name, *property_sig; - DBusMessageIter msg_iter; - DBusMessageIter variant_iter; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - if (pa_streq(dbus_message_get_signature(msg), "ssv")) { - pa_assert_se(dbus_message_iter_init(msg, &msg_iter)); - dbus_message_iter_get_basic(&msg_iter, &interface_name); - pa_assert_se(dbus_message_iter_next(&msg_iter)); - dbus_message_iter_get_basic(&msg_iter, &property_name); - pa_assert_se(dbus_message_iter_next(&msg_iter)); - - dbus_message_iter_recurse(&msg_iter, &variant_iter); - - property_sig = dbus_message_iter_get_signature(&variant_iter); - - if (pa_streq(interface_name, INTERFACE_POLICY)) { - for (prop_idx = 0; prop_idx < PROPERTY_MAX; prop_idx++) { - if (pa_streq(property_name, property_handlers[prop_idx].property_name)) { - if (pa_streq(property_handlers[prop_idx].type,property_sig)) { - property_handlers[prop_idx].set_cb(conn, msg, &variant_iter, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } - else{ - pa_log_warn("Wrong Property Signature"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_SIGNATURE, "Wrong Signature, Expected (ssv)"); - } - break; - } - } - } - else{ - pa_log_warn("Not our interface, not handle it"); - } - } else{ - pa_log_warn("Wrong Signature"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_SIGNATURE, "Wrong Signature, Expected (ssv)"); - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult handle_policy_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - int method_idx = 0; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - for (method_idx = 0; method_idx < METHOD_HANDLER_MAX; method_idx++) { - if (dbus_message_is_method_call(msg, INTERFACE_POLICY, method_handlers[method_idx].method_name )) { - if (pa_streq(dbus_message_get_signature(msg), method_arg_signatures[method_idx])) { - method_handlers[method_idx].receive_cb(conn, msg, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } - else{ - pa_log_warn("Wrong Argument Signature"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_SIGNATURE, "Wrong Signature, Expected %s", method_arg_signatures[method_idx]); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - } - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata) -{ - const char *xml = POLICY_INTROSPECT_XML; - DBusMessage *r = NULL; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se(r = dbus_message_new_method_return(msg)); - pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)); - - if (r) { - pa_assert_se(dbus_connection_send((conn), r, NULL)); - dbus_message_unref(r); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult method_call_handler(DBusConnection *c, DBusMessage *m, void *userdata) -{ - struct userdata *u = userdata; - const char *path, *interface, *member; - - pa_assert(c); - pa_assert(m); - pa_assert(u); - - path = dbus_message_get_path(m); - interface = dbus_message_get_interface(m); - member = dbus_message_get_member(m); - - pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member); - - if (!pa_streq(path, OBJECT_PATH)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { - return handle_introspect(c, m, u); - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Get")){ - return handle_get_property(c, m, u); - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set")){ - return handle_set_property(c, m, u); - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "GetAll")){ - return handle_get_all_property(c, m, u); - } else{ - return handle_policy_methods(c, m, u); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void endpoint_init(struct userdata *u) -{ - static const DBusObjectPathVTable vtable_endpoint = { - .message_function = method_call_handler, - }; - - pa_log_debug("Dbus endpoint init"); - - if (u && u->dbus_conn) { - if(!dbus_connection_register_object_path(pa_dbus_connection_get(u->dbus_conn), OBJECT_PATH, &vtable_endpoint, u)) - pa_log_error("Failed to register object path"); - } else{ - pa_log_error("Cannot get dbus connection to register object path"); - } -} - -static void endpoint_done(struct userdata* u) -{ - pa_log_debug("Dbus endpoint done"); - if (u && u->dbus_conn) { - if(!dbus_connection_unregister_object_path(pa_dbus_connection_get(u->dbus_conn), OBJECT_PATH)) - pa_log_error("Failed to unregister object path"); - } else{ - pa_log_error("Cannot get dbus connection to unregister object path"); - } -} - -static int watch_signals(struct userdata* u) -{ - DBusError error; - - dbus_error_init(&error); - - pa_log_debug("Watch Dbus signals"); - - if (u && u->dbus_conn) { - - if (!dbus_connection_add_filter(pa_dbus_connection_get(u->dbus_conn), dbus_filter_audio_handler, u, NULL)) { - pa_log_error("Unable to add D-Bus filter : %s: %s", error.name, error.message); - goto fail; - } - - if (pa_dbus_add_matches(pa_dbus_connection_get(u->dbus_conn), &error, SOUND_SERVER_FILTER, AUDIO_CLIENT_FILTER, NULL) < 0) { - pa_log_error("Unable to subscribe to signals: %s: %s", error.name, error.message); - goto fail; - } - return 0; - } - -fail: - dbus_error_free(&error); - return -1; -} - -static void unwatch_signals(struct userdata* u) -{ - pa_log_debug("Unwatch Dbus signals"); - - if (u && u->dbus_conn) { - pa_dbus_remove_matches(pa_dbus_connection_get(u->dbus_conn), SOUND_SERVER_FILTER, AUDIO_CLIENT_FILTER, NULL); - dbus_connection_remove_filter(pa_dbus_connection_get(u->dbus_conn), dbus_filter_audio_handler, u); - } -} - - - -static void dbus_init(struct userdata* u) -{ - DBusError error; - pa_dbus_connection *connection = NULL; - - pa_log_debug("Dbus init"); - dbus_error_init(&error); - - if (!(connection = pa_dbus_bus_get(u->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { - if (connection) { - pa_dbus_connection_unref(connection); - } - pa_log_error("Unable to contact D-Bus system bus: %s: %s", error.name, error.message); - goto fail; - } else{ - pa_log_debug("Got dbus connection"); - } - - u->dbus_conn = connection; - - if( watch_signals(u) < 0 ) - pa_log_error("dbus watch signals failed"); - else - pa_log_debug("dbus ready to get signals"); - - endpoint_init(u); - -fail: - dbus_error_free(&error); - -} - -static void dbus_deinit(struct userdata* u) -{ - pa_log_debug("Dbus deinit"); - if (u) { - - endpoint_done(u); - unwatch_signals(u); - - if (u->dbus_conn){ - pa_dbus_connection_unref(u->dbus_conn); - u->dbus_conn = NULL; - } - } -} -#endif - -int pa__init(pa_module *m) -{ - pa_modargs *ma = NULL; - struct userdata *u; - char *args = NULL; - - pa_assert(m); - - if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("Failed to parse module arguments"); - goto fail; - } - - m->userdata = u = pa_xnew0(struct userdata, 1); - u->core = m->core; - u->module = m; - -#ifdef HAVE_DBUS - u->dbus_conn = NULL; - u->test_property1 = 123; -#endif - - u->protocol = pa_native_protocol_get(m->core); - pa_native_protocol_install_ext(u->protocol, m, extension_cb); - - u->hal_manager = pa_hal_manager_get(u->core, (void *)u); - - u->communicator.comm = pa_communicator_get(u->core); - if (u->communicator.comm) { - u->communicator.comm_hook_select_proper_sink_or_source_slot = pa_hook_connect( - pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_SELECT_INIT_SINK_OR_SOURCE), - PA_HOOK_EARLY, (pa_hook_cb_t)select_proper_sink_or_source_hook_cb, u); - u->communicator.comm_hook_change_route_slot = pa_hook_connect( - pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_CHANGE_ROUTE), - PA_HOOK_EARLY, (pa_hook_cb_t)route_change_hook_cb, u); - u->communicator.comm_hook_update_route_option_slot = pa_hook_connect( - pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_UPDATE_ROUTE_OPTION), - PA_HOOK_EARLY, (pa_hook_cb_t)route_option_update_hook_cb, u); - u->communicator.comm_hook_device_connection_changed_slot = pa_hook_connect( - pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), - PA_HOOK_EARLY, (pa_hook_cb_t)device_connection_changed_hook_cb, u); - } - u->stream_manager = pa_stream_manager_init(u->core); - -#ifdef DEVICE_MANAGER - u->device_manager = pa_device_manager_init(u->core); -#endif - - /* load null sink/source */ - args = pa_sprintf_malloc("sink_name=%s", SINK_NULL); - u->module_null_sink = pa_module_load(u->module->core, "module-null-sink", args); - pa_xfree(args); - args = pa_sprintf_malloc("source_name=%s", SOURCE_NULL); - u->module_null_source = pa_module_load(u->module->core, "module-null-source", args); - pa_xfree(args); - - __load_dump_config(u); - -#ifdef HAVE_DBUS - dbus_init(u); -#endif - - pa_log_info("policy module is loaded\n"); - - if (ma) - pa_modargs_free(ma); - - return 0; - -fail: - if (ma) - pa_modargs_free(ma); - - pa__done(m); - - return -1; -} - -void pa__done(pa_module *m) -{ - struct userdata* u; - - pa_assert(m); - - if (!(u = m->userdata)) - return; - - pa_module_unload(u->module->core, u->module_null_sink, TRUE); - u->module_null_sink = NULL; - pa_module_unload(u->module->core, u->module_null_source, TRUE); - u->module_null_source = NULL; - -#ifdef HAVE_DBUS - dbus_deinit(u); -#endif -#ifdef DEVICE_MANAGER - if (u->device_manager) - pa_device_manager_done(u->device_manager); -#endif - if (u->protocol) { - pa_native_protocol_remove_ext(u->protocol, m); - pa_native_protocol_unref(u->protocol); - } - - if (u->stream_manager) - pa_stream_manager_done(u->stream_manager); - - if (u->communicator.comm) { - if (u->communicator.comm_hook_change_route_slot) - pa_hook_slot_free(u->communicator.comm_hook_change_route_slot); - if (u->communicator.comm_hook_change_route_slot) - pa_hook_slot_free(u->communicator.comm_hook_update_route_option_slot); - if (u->communicator.comm_hook_device_connection_changed_slot) - pa_hook_slot_free(u->communicator.comm_hook_device_connection_changed_slot); - pa_communicator_unref(u->communicator.comm); - } - - if (u->hal_manager) - pa_hal_manager_unref(u->hal_manager); - - pa_xfree(u); - - - pa_log_info("policy module is unloaded\n"); -} diff --git a/src/modules/tizen/module-tizenaudio-sink.c b/src/modules/tizen/module-tizenaudio-sink.c deleted file mode 100644 index c9d59f5..0000000 --- a/src/modules/tizen/module-tizenaudio-sink.c +++ /dev/null @@ -1,480 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2004-2008 Lennart Poettering - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tizen-audio.h" -#include "module-tizenaudio-sink-symdef.h" - - -PA_MODULE_AUTHOR("Tizen"); -PA_MODULE_DESCRIPTION("TizenAudio sink"); -PA_MODULE_VERSION(PACKAGE_VERSION); -PA_MODULE_LOAD_ONCE(false); -PA_MODULE_USAGE( - "name= " - "sink_name= " - "sink_properties= " - "namereg_fail= " - "device= " - "device_id= " - "format= " - "rate= " - "channels= " - "channel_map="); - -#define DEFAULT_SINK_NAME "tizenaudio" -#define BLOCK_USEC (PA_USEC_PER_SEC * 0.032) - -struct userdata { - pa_core *core; - pa_module *module; - pa_sink *sink; - - pa_thread *thread; - pa_thread_mq thread_mq; - pa_rtpoll *rtpoll; - - snd_pcm_t *pcm_handle; - - pa_usec_t block_usec; - pa_usec_t timestamp; - - char* device_name; - bool first, after_rewind; - - uint64_t write_count; - uint64_t since_start; -}; - -static const char* const valid_modargs[] = { - "name", - "sink_name", - "sink_properties", - "namereg_fail", - "device", - "device_id", - "format", - "rate", - "channels", - "channel_map", - NULL -}; - -/* Called from IO context */ -static int suspend(struct userdata *u) { - void *audio_data; - audio_interface_t *audio_intf; - - pa_assert(u); - pa_assert(u->pcm_handle); - audio_data = pa_shared_get(u->core, "tizen-audio-data"); - audio_intf = pa_shared_get(u->core, "tizen-audio-interface"); - - /* Let's suspend -- we don't call snd_pcm_drain() here since that might - * take awfully long with our long buffer sizes today. */ - if (audio_intf && audio_intf->pcm_close) { - audio_intf->pcm_close(audio_data, u->pcm_handle); - u->pcm_handle = NULL; - } - pa_log_info("Device suspended...[%s]", u->device_name); - - return 0; -} - -/* Called from IO context */ -static int unsuspend(struct userdata *u) { - pa_sample_spec sample_spec; - void *audio_data; - audio_interface_t *audio_intf; - - pa_assert(u); - pa_assert(!u->pcm_handle); - - pa_log_info("Trying resume..."); - - audio_data = pa_shared_get(u->core, "tizen-audio-data"); - audio_intf = pa_shared_get(u->core, "tizen-audio-interface"); - sample_spec = u->sink->sample_spec; - - if (audio_intf && audio_intf->pcm_open) { - audio_return_t audio_ret = AUDIO_RET_OK; - if (AUDIO_IS_ERROR((audio_ret = audio_intf->pcm_open(audio_data, (void **)&u->pcm_handle, &sample_spec, AUDIO_DIRECTION_OUT)))) { - pa_log("Error opening PCM device %x", audio_ret); - goto fail; - } - } - pa_log_info("Trying sw param..."); - - u->write_count = 0; - u->first = true; - u->since_start = 0; - - pa_log_info("Resumed successfully..."); - - return 0; - -fail: - if (u->pcm_handle) { - if (audio_intf && audio_intf->pcm_close) - audio_intf->pcm_close(audio_data, u->pcm_handle); - - u->pcm_handle = NULL; - } - return -PA_ERR_IO; -} - -static int sink_process_msg( - pa_msgobject *o, - int code, - void *data, - int64_t offset, - pa_memchunk *chunk) { - - struct userdata *u = PA_SINK(o)->userdata; - int r; - - switch (code) { - case PA_SINK_MESSAGE_SET_STATE: - switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) { - case PA_SINK_SUSPENDED: { - pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state)); - if ((r = suspend(u)) < 0) - return r; - - break; - } - - case PA_SINK_IDLE: - case PA_SINK_RUNNING: { - u->timestamp = pa_rtclock_now(); - if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { - if ((r = unsuspend(u)) < 0) - return r; - } - break; - } - - case PA_SINK_UNLINKED: - case PA_SINK_INIT: - case PA_SINK_INVALID_STATE: - break; - } - break; - - case PA_SINK_MESSAGE_GET_LATENCY: { - pa_usec_t now; - - now = pa_rtclock_now(); - *((pa_usec_t*) data) = u->timestamp > now ? u->timestamp - now : 0ULL; - - return 0; - } - } - - return pa_sink_process_msg(o, code, data, offset, chunk); -} - -static void sink_update_requested_latency_cb(pa_sink *s) { - struct userdata *u; - size_t nbytes; - - pa_sink_assert_ref(s); - pa_assert_se(u = s->userdata); - - u->block_usec = pa_sink_get_requested_latency_within_thread(s); - - if (u->block_usec == (pa_usec_t) -1) - u->block_usec = s->thread_info.max_latency; - - nbytes = pa_usec_to_bytes(u->block_usec, &s->sample_spec); - pa_sink_set_max_rewind_within_thread(s, nbytes); - pa_sink_set_max_request_within_thread(s, nbytes); -} - -static void process_rewind(struct userdata *u, pa_usec_t now) { - size_t rewind_nbytes, in_buffer; - pa_usec_t delay; - - pa_assert(u); - - rewind_nbytes = u->sink->thread_info.rewind_nbytes; - - if (!PA_SINK_IS_OPENED(u->sink->thread_info.state) || rewind_nbytes <= 0) - goto do_nothing; - - pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes); - - if (u->timestamp <= now) - goto do_nothing; - - delay = u->timestamp - now; - in_buffer = pa_usec_to_bytes(delay, &u->sink->sample_spec); - - if (in_buffer <= 0) - goto do_nothing; - - if (rewind_nbytes > in_buffer) - rewind_nbytes = in_buffer; - - pa_sink_process_rewind(u->sink, rewind_nbytes); - u->timestamp -= pa_bytes_to_usec(rewind_nbytes, &u->sink->sample_spec); - - pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes); - return; - -do_nothing: - - pa_sink_process_rewind(u->sink, 0); -} - -static void process_render(struct userdata *u, pa_usec_t now) { - size_t ate = 0; - void *p; - snd_pcm_sframes_t frames_to_write; - size_t frame_size; - audio_interface_t *audio_intf = pa_shared_get(u->core, "tizen-audio-interface"); - - pa_assert(u); - - /* This is the configured latency. Sink inputs connected to us - might not have a single frame more than the maxrequest value - queued. Hence: at maximum read this many bytes from the sink - inputs. */ - - /* Fill the buffer up the latency size */ - while (u->timestamp < now + u->block_usec) { - pa_memchunk chunk; - - audio_intf->pcm_avail(u->pcm_handle); - frame_size = pa_frame_size(&u->sink->sample_spec); - frames_to_write = u->sink->thread_info.max_request / frame_size; - - pa_sink_render_full(u->sink, frames_to_write * frame_size, &chunk); - p = pa_memblock_acquire(chunk.memblock); - - audio_intf->pcm_write(u->pcm_handle,(const uint8_t*) p + chunk.index, (snd_pcm_uframes_t) frames_to_write); - - pa_memblock_release(chunk.memblock); - pa_memblock_unref(chunk.memblock); - u->timestamp += pa_bytes_to_usec(chunk.length, &u->sink->sample_spec); - - ate += chunk.length; - if (ate >= u->sink->thread_info.max_request) { - break; - } - } -} - -static void thread_func(void *userdata) { - struct userdata *u = userdata; - - pa_assert(u); - pa_log_debug("Thread starting up"); - pa_thread_mq_install(&u->thread_mq); - u->timestamp = pa_rtclock_now(); - - for (;;) { - pa_usec_t now = 0; - int ret; - - if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) - now = pa_rtclock_now(); - - if (PA_UNLIKELY(u->sink->thread_info.rewind_requested)) - process_rewind(u, now); - - /* Render some data and drop it immediately */ - if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) { - if (u->timestamp <= now) { - process_render(u, now); - } - pa_rtpoll_set_timer_absolute(u->rtpoll, u->timestamp); - } else - pa_rtpoll_set_timer_disabled(u->rtpoll); - - /* Hmm, nothing to do. Let's sleep */ - if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0) - goto fail; - - if (ret == 0) - goto finish; - } - -fail: - /* If this was no regular exit from the loop we have to continue - * processing messages until we received PA_MESSAGE_SHUTDOWN */ - pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); - pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); - -finish: - pa_log_debug("Thread shutting down"); -} - -int pa__init(pa_module*m) { - struct userdata *u = NULL; - pa_sample_spec ss; - pa_channel_map map; - pa_modargs *ma = NULL; - pa_sink_new_data data; - size_t nbytes; - uint32_t alternate_sample_rate; - - pa_assert(m); - - if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { - pa_log("Failed to parse module arguments."); - goto fail; - } - - ss = m->core->default_sample_spec; - map = m->core->default_channel_map; - if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) { - pa_log("Invalid sample format specification or channel map"); - goto fail; - } - - alternate_sample_rate = m->core->alternate_sample_rate; - if (pa_modargs_get_alternate_sample_rate(ma, &alternate_sample_rate) < 0) { - pa_log("Failed to parse alternate sample rate"); - goto fail; - } - - m->userdata = u = pa_xnew0(struct userdata, 1); - u->core = m->core; - u->module = m; - u->rtpoll = pa_rtpoll_new(); - pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); - - pa_sink_new_data_init(&data); - data.driver = __FILE__; - data.module = m; - pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME)); - pa_sink_new_data_set_sample_spec(&data, &ss); - pa_sink_new_data_set_channel_map(&data, &map); - pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, _("Tizen audio sink")); - pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract"); - - if (pa_modargs_get_proplist(ma, "sink_properties", data.proplist, PA_UPDATE_REPLACE) < 0) { - pa_log("Invalid properties"); - pa_sink_new_data_done(&data); - goto fail; - } - - u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY); - pa_sink_new_data_done(&data); - - if (!u->sink) { - pa_log("Failed to create sink object."); - goto fail; - } - - u->sink->parent.process_msg = sink_process_msg; - u->sink->update_requested_latency = sink_update_requested_latency_cb; - u->sink->userdata = u; - - pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq); - pa_sink_set_rtpoll(u->sink, u->rtpoll); - - unsuspend (u); - - u->block_usec = BLOCK_USEC; - nbytes = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec); - pa_sink_set_max_rewind(u->sink, 0); - pa_sink_set_max_request(u->sink, nbytes); - - if (!(u->thread = pa_thread_new("tizenaudio-sink", thread_func, u))) { - pa_log("Failed to create thread."); - goto fail; - } - pa_sink_set_fixed_latency(u->sink, 32000); - pa_sink_put(u->sink); - pa_modargs_free(ma); - - return 0; - -fail: - if (ma) - pa_modargs_free(ma); - - pa__done(m); - return -1; -} - -int pa__get_n_used(pa_module *m) { - struct userdata *u; - - pa_assert(m); - pa_assert_se(u = m->userdata); - - return pa_sink_linked_by(u->sink); -} - -void pa__done(pa_module*m) { - struct userdata *u; - - pa_assert(m); - - if (!(u = m->userdata)) - return; - - if (u->sink) - pa_sink_unlink(u->sink); - - if (u->thread) { - pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); - pa_thread_free(u->thread); - } - - pa_thread_mq_done(&u->thread_mq); - - if (u->sink) - pa_sink_unref(u->sink); - - if (u->rtpoll) - pa_rtpoll_free(u->rtpoll); - - pa_xfree(u); -} diff --git a/src/modules/tizen/stream-manager-priv.h b/src/modules/tizen/stream-manager-priv.h deleted file mode 100644 index 8e8feb0..0000000 --- a/src/modules/tizen/stream-manager-priv.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef foostreammanagerprivfoo -#define foostreammanagerprivfoo - -#include "stream-manager.h" -#include "hal-manager.h" -#include "communicator.h" -#include "device-manager.h" - -#include -#include -#ifdef HAVE_DBUS -#include -#include -#include -#endif - -#define GET_STREAM_NEW_PROPLIST(stream, type) \ - (type == STREAM_SINK_INPUT? ((pa_sink_input_new_data*)stream)->proplist : ((pa_source_output_new_data*)stream)->proplist) - -#define GET_STREAM_PROPLIST(stream, type) \ - (type == STREAM_SINK_INPUT? ((pa_sink_input*)stream)->proplist : ((pa_source_output*)stream)->proplist) - -#define GET_STREAM_NEW_SAMPLE_SPEC(stream, type) \ - (type == STREAM_SINK_INPUT? ((pa_sink_input_new_data*)stream)->sample_spec : ((pa_source_output_new_data*)stream)->sample_spec) - -#define GET_STREAM_SAMPLE_SPEC(stream, type) \ - (type == STREAM_SINK_INPUT? ((pa_sink_input*)stream)->sample_spec : ((pa_source_output*)stream)->sample_spec) - -#define IS_FOCUS_ACQUIRED(focus, type) \ - (type == STREAM_SINK_INPUT? (focus & STREAM_FOCUS_ACQUIRED_PLAYBACK) : (focus & STREAM_FOCUS_ACQUIRED_CAPTURE)) - -enum stream_direction { - STREAM_DIRECTION_IN, - STREAM_DIRECTION_OUT, - STREAM_DIRECTION_MAX, -}; - -typedef struct _stream_info { - int32_t priority; - const char *volume_type[STREAM_DIRECTION_MAX]; - stream_route_type_t route_type; - pa_idxset *idx_avail_in_devices; - pa_idxset *idx_avail_out_devices; - pa_idxset *idx_avail_frameworks; -} stream_info; - -typedef struct _volume_info { - pa_bool_t is_hal_volume_type; - struct _values { - pa_bool_t is_muted; - uint32_t current_level; - pa_idxset *idx_volume_values; - } values[STREAM_DIRECTION_MAX]; -} volume_info; - -typedef struct _prior_max_priority_stream { - pa_sink_input *sink_input; - pa_source_output *source_output; - pa_bool_t need_to_update_si; - pa_bool_t need_to_update_so; -} cur_max_priority_stream; - -struct _stream_manager { - pa_core *core; - pa_hal_manager *hal; - pa_hashmap *volume_infos; - pa_hashmap *volume_modifiers; - pa_hashmap *stream_infos; - pa_hashmap *stream_parents; - cur_max_priority_stream cur_highest_priority; - pa_hook_slot - *sink_input_new_slot, - *sink_input_put_slot, - *sink_input_unlink_slot, - *sink_input_state_changed_slot, - *sink_input_move_start_slot, - *sink_input_move_finish_slot, - *source_output_new_slot, - *source_output_put_slot, - *source_output_unlink_slot, - *source_output_state_changed_slot; -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - pa_dbus_protocol *dbus_protocol; -#else - pa_dbus_connection *dbus_conn; -#endif -#endif - pa_subscription *subscription; - struct { - pa_communicator *comm; - pa_hook_slot *comm_hook_device_connection_changed_slot; - pa_hook_slot *comm_hook_device_information_changed_slot; - } comm; -}; - - -#endif diff --git a/src/modules/tizen/stream-manager-volume-priv.h b/src/modules/tizen/stream-manager-volume-priv.h deleted file mode 100644 index f4a9a0f..0000000 --- a/src/modules/tizen/stream-manager-volume-priv.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef foostreammanagervolumeprivfoo -#define foostreammanagervolumeprivfoo - -#include "stream-manager.h" - -#include -#include - -#define VCONFKEY_OUT_VOLUME_PREFIX "file/private/sound/volume/" -#define MASTER_VOLUME_TYPE "master" -#define MASTER_VOLUME_LEVEL_MAX 100 - -typedef enum { - GET_VOLUME_CURRENT_LEVEL, - GET_VOLUME_MAX_LEVEL -} pa_volume_get_command_t; - -int32_t init_volumes(pa_stream_manager *m); -void deinit_volumes(pa_stream_manager *m); -int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t volume_level); -int32_t get_volume_level_by_type(pa_stream_manager *m, pa_volume_get_command_t command, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level); -int32_t set_volume_level_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t idx, uint32_t volume_level); -int32_t set_volume_level_with_new_data(pa_stream_manager *m, stream_type_t stream_type, void *nd, uint32_t volume_level); -int32_t set_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t volume_mute); -int32_t get_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t *volume_mute); -int32_t set_volume_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t volume_mute); -int32_t set_volume_mute_with_new_data(pa_stream_manager *m, stream_type_t stream_type, void *nd, pa_bool_t volume_mute); -int32_t get_volume_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t *volume_mute); - -#endif diff --git a/src/modules/tizen/stream-manager-volume.c b/src/modules/tizen/stream-manager-volume.c deleted file mode 100644 index 009d0de..0000000 --- a/src/modules/tizen/stream-manager-volume.c +++ /dev/null @@ -1,858 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2015 Sangchul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include "stream-manager-priv.h" -#include "stream-manager-volume.h" -#include "stream-manager-volume-priv.h" - -#define VOLUME_INI_DEFAULT_PATH "/usr/etc/mmfw_audio_volume.ini" -#define VOLUME_INI_TUNED_PATH "/opt/system/mmfw_audio_volume.ini" -#define DEFAULT_TABLE "volumes" - -/* TODO : after preparing gain map, we can remove it */ -static const char *__get_gain_type_string_by_idx (uint32_t gain_type_idx) { - switch (gain_type_idx) { - case AUDIO_GAIN_TYPE_DEFAULT: return "default"; - case AUDIO_GAIN_TYPE_DIALER: return "dialer"; - case AUDIO_GAIN_TYPE_TOUCH: return "touch"; - case AUDIO_GAIN_TYPE_AF: return "af"; - case AUDIO_GAIN_TYPE_SHUTTER1: return "shutter1"; - case AUDIO_GAIN_TYPE_SHUTTER2: return "shutter2"; - case AUDIO_GAIN_TYPE_CAMCODING: return "camcording"; - case AUDIO_GAIN_TYPE_MIDI: return "midi"; - case AUDIO_GAIN_TYPE_BOOTING: return "booting"; - case AUDIO_GAIN_TYPE_VIDEO: return "video"; - case AUDIO_GAIN_TYPE_TTS: return "tts"; - default: return "invalid"; - } -} - -static int load_out_volume_conf_file (pa_stream_manager *m) { - int ret = 0; - dictionary *dict = NULL; - uint32_t gain_type_idx = 0; - int size = 0; - const char delimiter[] = ", "; - char *key = NULL; - char *list_str = NULL; - char *token = NULL; - char *ptr = NULL; - const char *table_str = DEFAULT_TABLE; - volume_info* v = NULL; - void *state = NULL; - const char *vol_type_str = NULL; - pa_assert(m); - - dict = iniparser_load(VOLUME_INI_TUNED_PATH); - if (!dict) { - pa_log_warn("Loading tuned volume & gain table from ini file failed"); - dict = iniparser_load(VOLUME_INI_DEFAULT_PATH); - if (!dict) { - pa_log_warn("Loading default volume & gain table from ini file failed"); - ret = -1; - goto FAILURE; - } - } - - /* Load volume table */ - while ((v = pa_hashmap_iterate(m->volume_infos, &state, (const void**)&vol_type_str))) { - size = strlen(table_str) + strlen(vol_type_str) + 2; - key = pa_xmalloc0(size); - if (key) { - snprintf(key, size, "%s:%s", table_str, vol_type_str); - list_str = iniparser_getstring(dict, key, NULL); - if (list_str) { - token = strtok_r(list_str, delimiter, &ptr); - while (token) { - /* convert dB volume to linear volume */ - double *vol_value = pa_xmalloc0(sizeof(double)); - *vol_value = 0.0f; - if(strncmp(token, "0", strlen(token))) - *vol_value = pow(10.0, (atof(token) - 100) / 20.0); - if (!v->values[STREAM_DIRECTION_OUT].idx_volume_values) - v->values[STREAM_DIRECTION_OUT].idx_volume_values = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - pa_idxset_put(v->values[STREAM_DIRECTION_OUT].idx_volume_values, vol_value, NULL); - token = strtok_r(NULL, delimiter, &ptr); - } - } else { - pa_log_warn("[%s] is not defined, skip it", key); - } - } else { - pa_log_error("failed to pa_xmalloc0()"); - ret = -1; - goto FAILURE; - } - if (key) { - free(key); - key = NULL; - } - } - - /* Load gain table */ - for (gain_type_idx = AUDIO_GAIN_TYPE_DEFAULT + 1; gain_type_idx < AUDIO_GAIN_TYPE_MAX; gain_type_idx++) { - const char *gain_type_str = __get_gain_type_string_by_idx(gain_type_idx); - size = strlen(table_str) + strlen("gain") + strlen(gain_type_str) + 3; - key = pa_xmalloc0(size); - if (key) { - snprintf(key, size, "%s:gain_%s", table_str, gain_type_str); - token = iniparser_getstring(dict, key, NULL); - if (token) { - double *modifier_gain = pa_xmalloc0(sizeof(double)); - *modifier_gain = atof(token); - if (!m->volume_modifiers) - m->volume_modifiers = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - pa_hashmap_put(m->volume_modifiers, (void*)gain_type_str, modifier_gain); - } else { - pa_log_warn("[%s] is not defined, skip it", key); - } - } else { - pa_log_error("failed to pa_xmalloc0()"); - ret = -1; - goto FAILURE; - } - if (key) { - free(key); - key = NULL; - } - } - -FAILURE: - if (key) - free(key); - if (dict) - iniparser_freedict(dict); - - return ret; -} - -static int is_hal_volume_by_type(pa_stream_manager *m, const char *volume_type, pa_bool_t *is_hal_volume) { - volume_info *v = NULL; - pa_assert(m); - pa_assert(volume_type); - pa_assert(is_hal_volume); - - if (m->volume_infos) { - v = pa_hashmap_get(m->volume_infos, volume_type); - if (v) - *is_hal_volume = v->is_hal_volume_type; - else - return -1; - } else - return -1; - - return 0; -} - -static int get_volume_value(pa_stream_manager *m, stream_type_t stream_type, pa_bool_t is_hal_volume, const char *volume_type, uint32_t volume_level, double *volume_value) { - int ret = 0; - double volume_linear = 1.0; - pa_assert(m); - pa_assert(volume_type); - pa_assert(volume_value); - - /* Get volume value by type & level */ - if (is_hal_volume) { - /* Get value from HAL */ - if (pa_hal_manager_get_volume_value(m->hal, volume_type, NULL, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, volume_level, &volume_linear)) { - ret = -1; - goto FAILURE; - } - } else { - volume_info *v = NULL; - void *volumes = m->volume_infos; - /* Get value from stream-manager */ - if (volumes) { - v = pa_hashmap_get(volumes, volume_type); - if (v && v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].idx_volume_values) { - double *value = NULL; - value = pa_idxset_get_by_index(v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].idx_volume_values, volume_level); - if (value) { - volume_linear = *value; - /* Apply master volume */ - v = pa_hashmap_get(volumes, MASTER_VOLUME_TYPE); - if (v && !v->is_hal_volume_type) - volume_linear *= (double)(v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].current_level)/100.0; - } else { - pa_log_error("failed to pa_idxset_get_by_index()"); - ret = -1; - goto FAILURE; - } - } else { - pa_log_error("could not get volume value for stream_type[%d], volume_type[%s], level[%u]", stream_type, volume_type, volume_level); - ret = -1; - goto FAILURE; - } - } else { - pa_log_error("could not get volumes in volume infos, stream_type(%d), volume_type(%s)", stream_type, volume_type); - ret = -1; - goto FAILURE; - } - } - - *volume_value = volume_linear; - - pa_log_debug("get_volume_value() : stream_type[%d], volume_type[%s], level[%u], value[%f]", - stream_type, volume_type, volume_level, volume_linear); -FAILURE: - return ret; -} - -int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t volume_level) { - pa_bool_t is_hal_volume = FALSE; - volume_info *v = NULL; - double volume_linear = 1.0; - double *modifier_gain_value = NULL; - uint32_t idx = 0; - const char *volume_type_str = NULL; - const char *modifier_gain = NULL; - void *s = NULL; - pa_hashmap *volumes = NULL; - pa_cvolume cv; - pa_assert(m); - pa_assert(volume_type); - - /* Check if it is related to HAL volume */ - if (is_hal_volume_by_type(m, volume_type, &is_hal_volume)) { - pa_log_error("failed to is_hal_volume_by_type(), volume_type(%s)", volume_type); - return -1; - } - - if (is_hal_volume) - if (pa_hal_manager_set_volume_level(m->hal, volume_type, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, volume_level)) - return -1; - - volumes = m->volume_infos; - if (volumes) { - v = pa_hashmap_get(volumes, volume_type); - if (v) { - if (pa_streq(volume_type, MASTER_VOLUME_TYPE) && MASTER_VOLUME_LEVEL_MAX < volume_level) { - pa_log_error("could not set volume level of MASTER type, out of range(%u)", volume_level); - return -1; - } - v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].current_level = volume_level; - if (is_hal_volume && pa_streq(volume_type, MASTER_VOLUME_TYPE)) { - /* no need to update the value of pulseaudio stream */ - return 0; - } - } else { - pa_log_error("could not get volume_info, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - } else { - pa_log_error("could not get volumes in volume infos, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - - if (!pa_streq(volume_type, MASTER_VOLUME_TYPE)) { - if (get_volume_value(m, stream_type, is_hal_volume, volume_type, volume_level, &volume_linear)) - return -1; - - PA_IDXSET_FOREACH(s, stream_type==STREAM_SINK_INPUT?m->core->sink_inputs:m->core->source_outputs, idx) { - if ((volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - /* Get modifier for gain */ - modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); - } else { - continue; - } - /* Update volume level of stream if it has requested the volume type */ - if (pa_streq(volume_type_str, volume_type)) { - if (modifier_gain) { - if (m->volume_modifiers) { - modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain); - if (modifier_gain_value) { - volume_linear *= (*modifier_gain_value); - pa_log_info("set_volume_level_by_type() : apply the modifier for the gain value(%s=>%f), result volume_linear(%f)", - modifier_gain, *modifier_gain_value, volume_linear); - } - } - } - pa_cvolume_set(&cv, GET_STREAM_SAMPLE_SPEC(s, stream_type).channels, pa_sw_volume_from_linear(volume_linear)); - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_set_volume((pa_sink_input*)s, &cv, TRUE, TRUE); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_set_volume((pa_source_output*)s, &cv, TRUE, TRUE); - } - } - } else { - PA_IDXSET_FOREACH(s, stream_type==STREAM_SINK_INPUT?m->core->sink_inputs:m->core->source_outputs, idx) { - if ((volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - /* Get modifier for gain */ - modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); - /* Check if it is related to HAL volume */ - if (is_hal_volume_by_type(m, volume_type_str, &is_hal_volume)) { - pa_log_error("failed to is_hal_volume_by_type(), volume_type(%s)", volume_type_str); - continue; - } - /* Get volume level of this type */ - v = pa_hashmap_get(volumes, volume_type_str); - if (v) - volume_level = v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].current_level; - else - continue; - } else { - continue; - } - if (get_volume_value(m, stream_type, is_hal_volume, volume_type_str, volume_level, &volume_linear)) - continue; - - if (modifier_gain) { - if (m->volume_modifiers) { - modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain); - if (modifier_gain_value) { - volume_linear *= (*modifier_gain_value); - pa_log_info("set_volume_level_by_type() : apply the modifier for the gain value(%s=>%f), result volume_linear(%f)", - modifier_gain, *modifier_gain_value, volume_linear); - } - } - } - pa_cvolume_set(&cv, GET_STREAM_SAMPLE_SPEC(s, stream_type).channels, pa_sw_volume_from_linear(volume_linear)); - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_set_volume((pa_sink_input*)s, &cv, TRUE, TRUE); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_set_volume((pa_source_output*)s, &cv, TRUE, TRUE); - } - } - - pa_log_debug("set_volume_level_by_type() : stream_type[%d], volume_type[%s], level[%u], value[%f]", - stream_type, volume_type, volume_level, volume_linear); - - return 0; -} - -int32_t get_volume_level_by_type(pa_stream_manager *m, pa_volume_get_command_t command, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level) { - int32_t ret = 0; - pa_bool_t is_hal_volume = FALSE; - pa_hashmap *volumes = NULL; - pa_assert(m); - pa_assert(volume_type); - - /* Check if it is related to HAL volume */ - if (is_hal_volume_by_type(m, volume_type, &is_hal_volume)) { - pa_log_error("failed to is_hal_volume_by_type(), volume_type(%s)", volume_type); - return -1; - } - - if (command == GET_VOLUME_CURRENT_LEVEL) { - /* Get level */ - if (is_hal_volume) { - /* from HAL */ - if (pa_hal_manager_get_volume_level(m->hal, volume_type, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, volume_level)) - ret = -1; - } else { - /* from stream-manager */ - volumes = m->volume_infos; - if (volumes) { - volume_info *v = pa_hashmap_get(volumes, volume_type); - if (v) - *volume_level = v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].current_level; - else { - pa_log_error("could not get volume_info, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - } else { - pa_log_error("could not get volumes in volume infos, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - } - } else if (command == GET_VOLUME_MAX_LEVEL) { - /* If it is the master volume type */ - if (pa_streq(volume_type, MASTER_VOLUME_TYPE)) { - *volume_level = MASTER_VOLUME_LEVEL_MAX; - } else { - /* Get max level */ - if (is_hal_volume) { - /* from HAL */ - if (pa_hal_manager_get_volume_level_max(m->hal, volume_type, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, volume_level)) - ret = -1; - } else { - /* from stream-manager */ - volumes = m->volume_infos; - if (volumes) { - volume_info *v = pa_hashmap_get(volumes, volume_type); - if (v && v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].idx_volume_values) - *volume_level = pa_idxset_size(v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].idx_volume_values); - else { - pa_log_error("could not get volume_info, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - } else { - pa_log_error("could not get volumes in volume infos, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - } - } - } - - return ret; -} - -int32_t set_volume_level_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t idx, uint32_t volume_level) { - pa_bool_t is_hal_volume = FALSE; - void *s = NULL; - pa_cvolume cv; - double volume_linear = 1.0; - const char *volume_type_str = NULL; - const char *modifier_gain = NULL; - pa_assert(m); - - s = pa_idxset_get_by_index(stream_type==STREAM_SINK_INPUT?m->core->sink_inputs:m->core->source_outputs, idx); - if ((volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - /* Get modifier for gain */ - modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); - } else { - pa_log_debug("idx[%u] doesn't have volume type", idx); - return -1; - } - - /* Check if it is related to HAL volume */ - if (is_hal_volume_by_type(m, volume_type_str, &is_hal_volume)) { - pa_log_error("failed to is_hal_volume_by_type(), volume_type(%s)", volume_type_str); - return -1; - } - - if (is_hal_volume) - if (pa_hal_manager_set_volume_level(m->hal, volume_type_str, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, volume_level)) - return -1; - - if (!get_volume_value(m, stream_type, is_hal_volume, volume_type_str, volume_level, &volume_linear)) { - if (modifier_gain) { - double *modifier_gain_value = NULL; - modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain); - if (modifier_gain_value) { - volume_linear *= (*modifier_gain_value); - pa_log_info("set_volume_level_by_idx() : apply the modifier for the gain value(%s=>%f), result volume_linear(%f)", - modifier_gain, *modifier_gain_value, volume_linear); - } - } - pa_cvolume_set(&cv, GET_STREAM_SAMPLE_SPEC(s, stream_type).channels, pa_sw_volume_from_linear(volume_linear)); - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_set_volume((pa_sink_input*)s, &cv, TRUE, TRUE); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_set_volume((pa_source_output*)s, &cv, TRUE, TRUE); - } - pa_log_debug("set_volume_level_by_idx() : stream_type[%d], idx[%u]=>volume_type[%s], level[%u], value[%f]", - stream_type, idx, volume_type_str, volume_level, volume_linear); - - return 0; -} - -int32_t set_volume_level_with_new_data(pa_stream_manager *m, stream_type_t stream_type, void *nd, uint32_t volume_level) { - pa_bool_t is_hal_volume = FALSE; - pa_cvolume cv; - double volume_linear = 1.0; - const char *volume_type_str = NULL; - const char *modifier_gain = NULL; - pa_assert(m); - - if ((volume_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(nd, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - /* Get modifier for gain */ - modifier_gain = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(nd, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); - } else { - pa_log_debug("new_data[%p] doesn't have volume type", nd); - return -1; - } - - /* Check if it is related to HAL volume */ - if (is_hal_volume_by_type(m, volume_type_str, &is_hal_volume)) { - pa_log_error("failed to is_hal_volume_by_type(), volume_type(%s)", volume_type_str); - return -1; - } - - if (is_hal_volume) - if (pa_hal_manager_set_volume_level(m->hal, volume_type_str, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, volume_level)) - return -1; - - if (!get_volume_value(m, stream_type, is_hal_volume, volume_type_str, volume_level, &volume_linear)) { - if (modifier_gain) { - double *modifier_gain_value = NULL; - modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain); - if (modifier_gain_value) { - volume_linear *= (*modifier_gain_value); - pa_log_info("set_volume_level_by_idx() : apply the modifier for the gain value(%s=>%f), result volume_linear(%f)", - modifier_gain, *modifier_gain_value, volume_linear); - } - } - pa_cvolume_set(&cv, GET_STREAM_NEW_SAMPLE_SPEC(nd, stream_type).channels, pa_sw_volume_from_linear(volume_linear)); - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_new_data_set_volume((pa_sink_input_new_data*)nd, &cv, TRUE); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_new_data_set_volume((pa_source_output_new_data*)nd, &cv, TRUE); - } - pa_log_debug("set_volume_level_with_new_data() : stream_type[%d], volume_type[%s], level[%u], value[%f]", - stream_type, volume_type_str, volume_level, volume_linear); - - return 0; -} - -int32_t set_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t volume_mute) { - pa_bool_t is_hal_volume = FALSE; - volume_info *v = NULL; - void *s = NULL; - pa_hashmap *volumes = NULL; - uint32_t idx; - const char *volume_type_str = NULL; - pa_assert(m); - pa_assert(volume_type); - - /* Check if it is related to HAL volume */ - if (is_hal_volume_by_type(m, volume_type, &is_hal_volume)) { - pa_log_error("failed to is_hal_volume_by_type(), volume_type(%s)", volume_type); - return -1; - } - - if (is_hal_volume) - if (pa_hal_manager_set_mute(m->hal, volume_type, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, (uint32_t)volume_mute)) - return -1; - - /* Set mute */ - volumes = m->volume_infos; - if (volumes) { - v = pa_hashmap_get(volumes, volume_type); - if (v) - v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].is_muted = volume_mute; - else { - pa_log_error("could not get volume_info, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - } else { - pa_log_error("could not get volumes in volume infos, volume_type(%s)", volume_type); - return -1; - } - - PA_IDXSET_FOREACH(s, (stream_type==STREAM_SINK_INPUT)?m->core->sink_inputs:m->core->source_outputs, idx) { - if ((volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - /* do nothing */ - } else { - continue; - } - /* Update mute of stream if it has requested the volume type */ - if (pa_streq(volume_type_str, volume_type)) { - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_set_mute((pa_sink_input*)s, volume_mute, TRUE); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_set_mute((pa_source_output*)s, volume_mute, TRUE); - } - } - - pa_log_info("pa_stream_manager_volume_set_mute, stream_type:%d volume_type:%s mute:%d", stream_type, volume_type, volume_mute); - - return 0; -} - -int32_t get_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t *volume_mute) { - volume_info *v = NULL; - pa_hashmap *volumes = NULL; - pa_assert(m); - pa_assert(volume_type); - pa_assert(volume_mute); - - /* Get mute */ - volumes = m->volume_infos; - if (volumes) { - v = pa_hashmap_get(volumes, volume_type); - if (v) - *volume_mute = v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].is_muted; - else { - pa_log_error("could not get volume_info, stream_type(%d), volume_type(%s)", stream_type, volume_type); - return -1; - } - } else { - pa_log_error("could not get volumes in volume infos, volume_type(%s)", volume_type); - return -1; - } - - pa_log_info("pa_stream_manager_volume_get_mute, volume_type:%s mute:%d", volume_type, *volume_mute); - - return 0; -} - -int32_t set_volume_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t volume_mute) { - void *s = NULL; - uint32_t idx = 0; - const char *volume_type_str = NULL; - volume_info *v = NULL; - pa_hashmap *volumes = NULL; - pa_bool_t muted_by_type = FALSE; - pa_assert(m); - - pa_log_info("set_volume_mute_by_idx, stream_type:%d stream_idx:%u mute:%d", stream_type, stream_idx, volume_mute); - - if (stream_idx != (uint32_t)-1) { - if ((s = pa_idxset_get_by_index((stream_type==STREAM_SINK_INPUT)?m->core->sink_inputs:m->core->source_outputs, stream_idx))) { - if ((volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - /* do nothing */ - } else { - pa_log_warn("stream[%d] doesn't have volume type", stream_idx); - } - } else { - pa_log_warn("stream[%u] doesn't exist", stream_idx); - } - } - - /* Get mute state of the volume type of this stream */ - if (volume_type_str) { - volumes = m->volume_infos; - if (volumes) { - v = pa_hashmap_get(volumes, volume_type_str); - if (v) - muted_by_type = v->values[(stream_type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].is_muted; - } else { - pa_log_error("could not get volumes in volume map, stream_type(%d), volume_type(%s)", stream_type, volume_type_str); - return -1; - } - } - - if (!muted_by_type) { - PA_IDXSET_FOREACH(s, (stream_type==STREAM_SINK_INPUT)?m->core->sink_inputs:m->core->source_outputs, idx) { - /* Update mute of the stream if it has requested idx */ - if (stream_idx == idx) { - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_set_mute((pa_sink_input*)s, volume_mute, TRUE); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_set_mute((pa_source_output*)s, volume_mute, TRUE); - break; - } - } - } - - return 0; -} - -int32_t get_volume_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t *volume_mute) { - int32_t ret = 0; - void *s = NULL; - uint32_t idx = 0; - pa_assert(m); - pa_assert(volume_mute); - - PA_IDXSET_FOREACH(s, (stream_type==STREAM_SINK_INPUT)?m->core->sink_inputs:m->core->source_outputs, idx) { - /* Update mute of the stream if it has requested idx */ - if (stream_idx == idx) { - if (stream_type == STREAM_SINK_INPUT) - *volume_mute = ((pa_sink_input*)s)->muted; - else if (stream_type == STREAM_SOURCE_OUTPUT) - *volume_mute = ((pa_source_output*)s)->muted; - break; - } - } - if (!s) - ret = -1; - - pa_log_info("get_volume_mute_by_idx, stream_type:%d stream_idx:%u mute:%d, ret:%d", stream_type, stream_idx, *volume_mute, ret); - - return ret; -} - -int32_t set_volume_mute_with_new_data(pa_stream_manager *m, stream_type_t stream_type, void *nd, pa_bool_t volume_mute) { - pa_bool_t is_hal_volume = FALSE; - const char *volume_type_str = NULL; - pa_assert(m); - - pa_log_info("set_volume_mute_with_new_data, stream_type:%d mute:%d", stream_type, volume_mute); - - if ((volume_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(nd, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - /* do nothing */ - } else { - pa_log_debug("new_data[%p] doesn't have volume type", nd); - return -1; - } - - /* Check if it is related to HAL volume */ - if (is_hal_volume_by_type(m, volume_type_str, &is_hal_volume)) { - pa_log_error("failed to is_hal_volume_by_type(), volume_type(%s)", volume_type_str); - return -1; - } - - if (is_hal_volume) - if (pa_hal_manager_set_mute(m->hal, volume_type_str, (stream_type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN, volume_mute)) - return -1; - - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_new_data_set_muted((pa_sink_input_new_data*)nd, volume_mute); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_new_data_set_muted((pa_source_output_new_data*)nd, volume_mute); - - return 0; -} - -static void dump_volumes (pa_stream_manager *m) { - volume_info *s = NULL; - const char *volume_type = NULL; - const char *modifier_gain = NULL; - double *level = NULL; - double *gain_value = NULL; - void *state = NULL; - uint32_t idx = 0; - pa_assert(m); - - pa_log_debug("==========[START volume infos dump]=========="); - while (m->volume_infos && (s = pa_hashmap_iterate(m->volume_infos, &state, (const void**)&volume_type))) { - if (s) { - pa_log_debug("[volume_type : %s]", volume_type); - pa_log_debug(" - is_hal_volume_type : %d", s->is_hal_volume_type); - if (s->values[STREAM_DIRECTION_IN].idx_volume_values) { - pa_log_debug(" - (in)max level : %u", pa_idxset_size(s->values[STREAM_DIRECTION_IN].idx_volume_values)); - PA_IDXSET_FOREACH(level, s->values[STREAM_DIRECTION_IN].idx_volume_values, idx) - pa_log_debug(" - (in)value[%u] : %f", idx, *level); - } - if (s->values[STREAM_DIRECTION_OUT].idx_volume_values) { - pa_log_debug(" - (out)max level : %u", pa_idxset_size(s->values[STREAM_DIRECTION_OUT].idx_volume_values)); - PA_IDXSET_FOREACH(level, s->values[STREAM_DIRECTION_OUT].idx_volume_values, idx) - pa_log_debug(" - (out)value[%u] : %f", idx, *level); - } - } - } - state = NULL; - while (m->volume_modifiers && (gain_value = pa_hashmap_iterate(m->volume_modifiers, &state, (const void**)&modifier_gain))) - pa_log_debug("[modifier gain:%s, value:%f]", modifier_gain, *gain_value); - pa_log_debug("===========[END volume infos dump]==========="); - - return; -} - -int32_t init_volumes (pa_stream_manager *m) { - int ret = 0; - void *state = NULL; - volume_info *v = NULL; - pa_assert(m); - - /* For now, we only care about volumes for the output stream */ - ret = load_out_volume_conf_file(m); - if (ret) - pa_log_error("failed to load_out_volume_conf_file(), ret[%d]", ret); - - dump_volumes(m); - - /* Apply initial output volume level from vconf volume level */ - { - #define VCONF_ADDR_LEN 64 - char vconf_vol_type_addr[VCONF_ADDR_LEN] = {0,}; - const char *volume_type = NULL; - int level = 10; - state = NULL; - while ((v = pa_hashmap_iterate(m->volume_infos, &state, (const void**)&volume_type))) { - memset(vconf_vol_type_addr, 0, VCONF_ADDR_LEN); - pa_snprintf(vconf_vol_type_addr, VCONF_ADDR_LEN, "%s%s", VCONFKEY_OUT_VOLUME_PREFIX, volume_type); - if (vconf_get_int(vconf_vol_type_addr, &level)) - pa_log_error("failed to get volume level of the vconf[%s]", vconf_vol_type_addr); - else { - set_volume_level_by_type(m, STREAM_SINK_INPUT, volume_type, (uint32_t)level); - pa_log_debug("type(%s), current level(%u)", volume_type, v->values[STREAM_DIRECTION_OUT].current_level); - } - } - } -#if 0 - /* Apply initial output volume mute from vconf volume mute */ - { - - } -#endif - if (ret) - pa_log_error("Failed to initialize volumes"); - return ret; -} - -void deinit_volumes (pa_stream_manager *m) { - volume_info *v = NULL; - void *state = NULL; - uint32_t idx = 0; - double *level = NULL; - double *gain = NULL; - int i = 0; - pa_assert(m); - - if (m->volume_infos) { - PA_HASHMAP_FOREACH(v, m->volume_infos, state) { - for (i = 0; i < STREAM_DIRECTION_MAX; i++) { - if (v->values[i].idx_volume_values) { - PA_IDXSET_FOREACH(level, v->values[i].idx_volume_values, idx) - pa_xfree(level); - pa_idxset_free(v->values[i].idx_volume_values, NULL); - } - } - } - } - if (m->volume_modifiers) { - PA_HASHMAP_FOREACH(gain, m->volume_modifiers, state) - pa_xfree(gain); - pa_hashmap_free(m->volume_modifiers); - } - - return; -} - -int32_t pa_stream_manager_volume_get_max_level(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level) { - int32_t ret = 0; - pa_assert(m); - pa_assert(volume_type); - - ret = get_volume_level_by_type(m, GET_VOLUME_MAX_LEVEL, stream_type, volume_type, volume_level); - - pa_log_info("pa_stream_manager_volume_get_max_level, type:%s max_level:%u, ret:%d", volume_type, *volume_level, ret); - - return ret; -} - -int32_t pa_stream_manager_volume_get_level(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level) { - int32_t ret = 0; - pa_assert(m); - pa_assert(volume_type); - - ret = get_volume_level_by_type(m, GET_VOLUME_CURRENT_LEVEL, stream_type, volume_type, volume_level); - - pa_log_info("pa_stream_manager_volume_get_level, type:%s level:%u, ret:%d", volume_type, *volume_level, ret); - - return ret; -} - -int32_t pa_stream_manager_volume_set_level(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t volume_level) { - int32_t ret = 0; - pa_assert(m); - pa_assert(volume_type); - - ret = set_volume_level_by_type(m, stream_type, volume_type, volume_level); - - pa_log_info(" pa_stream_manager_volume_set_level, type:%s level:%u, ret:%d", volume_type, volume_level, ret); - - return ret; -} - -int32_t pa_stream_manager_volume_get_mute(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t *volume_mute) { - return get_volume_mute_by_type(m, stream_type, volume_type, volume_mute); -} - -int32_t pa_stream_manager_volume_set_mute(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t volume_mute) { - return set_volume_mute_by_type(m, stream_type, volume_type, volume_mute); -} - -int32_t pa_stream_manager_volume_get_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t *volume_mute) { - return get_volume_mute_by_idx(m, stream_type, stream_idx, volume_mute); -} - -int32_t pa_stream_manager_volume_set_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t volume_mute) { - return set_volume_mute_by_idx(m, stream_type, stream_idx, volume_mute); -} diff --git a/src/modules/tizen/stream-manager-volume.h b/src/modules/tizen/stream-manager-volume.h deleted file mode 100644 index e1d2718..0000000 --- a/src/modules/tizen/stream-manager-volume.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef foostreammanagervolumefoo -#define foostreammanagervolumefoo - -#include "stream-manager.h" - -int32_t pa_stream_manager_volume_get_level(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level); -int32_t pa_stream_manager_volume_set_level(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t volume_level); -int32_t pa_stream_manager_volume_get_mute(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t *volume_mute); -int32_t pa_stream_manager_volume_set_mute(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, pa_bool_t volume_mute); -int32_t pa_stream_manager_volume_get_max_level(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level); -int32_t pa_stream_manager_volume_get_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t *volume_mute); -int32_t pa_stream_manager_volume_set_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, pa_bool_t volume_mute); - -#endif diff --git a/src/modules/tizen/stream-manager.c b/src/modules/tizen/stream-manager.c deleted file mode 100644 index c229c0b..0000000 --- a/src/modules/tizen/stream-manager.c +++ /dev/null @@ -1,2632 +0,0 @@ -/*** - This file is part of PulseAudio. - - Copyright 2015 Sangchul Lee - - PulseAudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, - or (at your option) any later version. - - PulseAudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with PulseAudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include "stream-manager.h" -#include "stream-manager-priv.h" -#include "stream-manager-volume-priv.h" - -#ifdef HAVE_DBUS -#define ARR_ARG_MAX 32 -#define STREAM_MANAGER_OBJECT_PATH "/org/pulseaudio/StreamManager" -#define STREAM_MANAGER_INTERFACE "org.pulseaudio.StreamManager" -#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO "GetStreamInfo" -#define STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST "GetStreamList" -#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES "SetStreamRouteDevices" -#define STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION "SetStreamRouteOption" -#define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL "SetVolumeLevel" -#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL "GetVolumeLevel" -#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL "GetVolumeMaxLevel" -#define STREAM_MANAGER_METHOD_NAME_SET_VOLUME_MUTE "SetVolumeMute" -#define STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MUTE "GetVolumeMute" -#define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE "GetCurrentVolumeType" /* the type that belongs to the stream of the current max priority */ -#define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS "UpdateFocusStatus" - -static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m, void *userdata); -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata); -static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_stream_info(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_stream_list(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_stream_route_option(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata); - -enum method_handler_index { - METHOD_HANDLER_GET_STREAM_INFO, - METHOD_HANDLER_GET_STREAM_LIST, - METHOD_HANDLER_SET_STREAM_ROUTE_DEVICES, - METHOD_HANDLER_SET_STREAM_ROUTE_OPTION, - METHOD_HANDLER_SET_VOLUME_LEVEL, - METHOD_HANDLER_GET_VOLUME_LEVEL, - METHOD_HANDLER_GET_VOLUME_MAX_LEVEL, - METHOD_HANDLER_SET_VOLUME_MUTE, - METHOD_HANDLER_GET_VOLUME_MUTE, - METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE, - METHOD_HANDLER_UPDATE_FOCUS_STATUS, - METHOD_HANDLER_MAX -}; - -static pa_dbus_arg_info get_stream_info_args[] = { { "stream_type", "s", "in" }, - { "priority", "i", "out" }, - { "route_type", "i", "out" }, - { "avail_in_devices", "as", "out" }, - { "avail_out_devices", "as", "out" }, - { "avail_frameworks", "as", "out"} }; -static pa_dbus_arg_info get_stream_list_args[] = { { "stream_type", "as", "out" }, - { "priority", "ai", "out" } }; -static pa_dbus_arg_info set_stream_route_devices_args[] = { { "parent_id", "u", "in" }, - { "route_in_devices", "au", "in" }, - { "route_out_devices", "au", "in" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info set_stream_route_option_args[] = { { "parent_id", "u", "in" }, - { "name", "s", "in" }, - { "value", "i", "in" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info set_volume_level_args[] = { { "io_direction", "s", "in" }, - { "type", "s", "in" }, - { "level", "u", "in" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info get_volume_level_args[] = { { "io_direction", "s", "in" }, - { "type", "s", "in" }, - { "level", "u", "out" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info get_volume_max_level_args[] = { { "io_direction", "s", "in" }, - { "type", "s", "in" }, - { "level", "u", "out" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info set_volume_mute_args[] = { { "io_direction", "s", "in" }, - { "type", "s", "in" }, - { "on/off", "u", "in" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info get_volume_mute_args[] = { { "io_direction", "s", "in" }, - { "type", "s", "in" }, - { "on/off", "u", "out" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info get_current_volume_type_args[] = { { "io_direction", "s", "in" }, - { "type", "s", "out" }, - { "ret_msg", "s", "out" } }; -static pa_dbus_arg_info update_focus_status_args[] = { { "parent_id", "u", "in" }, - { "focus_status", "u", "in" }, - { "ret_msg", "s", "out" } }; -static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "uu"}; - -static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { - [METHOD_HANDLER_GET_STREAM_INFO] = { - .method_name = STREAM_MANAGER_METHOD_NAME_GET_STREAM_INFO, - .arguments = get_stream_info_args, - .n_arguments = sizeof(get_stream_info_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_get_stream_info }, - [METHOD_HANDLER_GET_STREAM_LIST] = { - .method_name = STREAM_MANAGER_METHOD_NAME_GET_STREAM_LIST, - .arguments = get_stream_list_args, - .n_arguments = sizeof(get_stream_list_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_get_stream_list }, - [METHOD_HANDLER_SET_STREAM_ROUTE_DEVICES] = { - .method_name = STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_DEVICES, - .arguments = set_stream_route_devices_args, - .n_arguments = sizeof(set_stream_route_devices_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_set_stream_route_devices }, - [METHOD_HANDLER_SET_STREAM_ROUTE_OPTION] = { - .method_name = STREAM_MANAGER_METHOD_NAME_SET_STREAM_ROUTE_OPTION, - .arguments = set_stream_route_option_args, - .n_arguments = sizeof(set_stream_route_option_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_set_stream_route_option }, - [METHOD_HANDLER_SET_VOLUME_LEVEL] = { - .method_name = STREAM_MANAGER_METHOD_NAME_SET_VOLUME_LEVEL, - .arguments = set_volume_level_args, - .n_arguments = sizeof(set_volume_level_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_set_volume_level }, - [METHOD_HANDLER_GET_VOLUME_LEVEL] = { - .method_name = STREAM_MANAGER_METHOD_NAME_GET_VOLUME_LEVEL, - .arguments = get_volume_level_args, - .n_arguments = sizeof(get_volume_level_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_get_volume_level }, - [METHOD_HANDLER_GET_VOLUME_MAX_LEVEL] = { - .method_name = STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MAX_LEVEL, - .arguments = get_volume_max_level_args, - .n_arguments = sizeof(get_volume_max_level_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_get_volume_max_level }, - [METHOD_HANDLER_SET_VOLUME_MUTE] = { - .method_name = STREAM_MANAGER_METHOD_NAME_SET_VOLUME_MUTE, - .arguments = set_volume_mute_args, - .n_arguments = sizeof(set_volume_mute_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_set_volume_mute }, - [METHOD_HANDLER_GET_VOLUME_MUTE] = { - .method_name = STREAM_MANAGER_METHOD_NAME_GET_VOLUME_MUTE, - .arguments = get_volume_mute_args, - .n_arguments = sizeof(get_volume_mute_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_get_volume_mute }, - [METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE] = { - .method_name = STREAM_MANAGER_METHOD_NAME_GET_CURRENT_VOLUME_TYPE, - .arguments = get_current_volume_type_args, - .n_arguments = sizeof(get_current_volume_type_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_get_current_volume_type }, - [METHOD_HANDLER_UPDATE_FOCUS_STATUS] = { - .method_name = STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS, - .arguments = update_focus_status_args, - .n_arguments = sizeof(update_focus_status_args) / sizeof(pa_dbus_arg_info), - .receive_cb = handle_update_focus_status }, -}; - -const char *dbus_str_none = "none"; -const char* stream_manager_dbus_ret_str[] = {"STREAM_MANAGER_RETURN_OK","STREAM_MANAGER_RETURN_ERROR", "STREAM_MANAGER_RETURN_ERROR_NO_STREAM"}; -enum { - RET_MSG_INDEX_OK, - RET_MSG_INDEX_ERROR, - RET_MSG_INDEX_ERROR_NO_STREAM, -}; - -#ifdef USE_DBUS_PROTOCOL - -static pa_dbus_interface_info stream_manager_interface_info = { - .name = STREAM_MANAGER_INTERFACE, - .method_handlers = method_handlers, - .n_method_handlers = METHOD_HANDLER_MAX, - .property_handlers = , - .n_property_handlers = , - .get_all_properties_cb =, - .signals =, - .n_signals = -}; - -#else - -#define STREAM_MGR_INTROSPECT_XML \ - DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ - "" \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " "\ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - " " \ - "" -#endif - -#endif - -#define STREAM_MANAGER_CLIENT_NAME "SOUND_MANAGER_STREAM_INFO" -#define DEFAULT_ROLE "media" -#define SKIP_ROLE "skip" - -/* There are some streams to be skipped. - * In other words, we do not care about streams that have a name of listed as below */ -#define NAME_FOR_SKIP_MAX 1 -const char* stream_manager_media_names_for_skip[NAME_FOR_SKIP_MAX] = {"pulsesink probe"}; - -#define STREAM_FOCUS_NONE "0" -#define STREAM_FOCUS_PLAYBACK "1" -#define STREAM_FOCUS_CAPTURE "2" - -typedef enum _focus_acquired_status { - STREAM_FOCUS_ACQUIRED_NONE = 0x00, - STREAM_FOCUS_ACQUIRED_PLAYBACK = 0x01, - STREAM_FOCUS_ACQUIRED_CAPTURE = 0x02, -} focus_acquired_status_t; - -typedef enum _process_stream_result { - PROCESS_STREAM_RESULT_OK, - PROCESS_STREAM_RESULT_STOP, - PROCESS_STREAM_RESULT_SKIP, -} process_stream_result_t; - -typedef enum _process_command_type { - PROCESS_COMMAND_PREPARE, - PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA, - PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, - PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, - PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED, - PROCESS_COMMAND_UPDATE_VOLUME, - PROCESS_COMMAND_ADD_PARENT_ID, - PROCESS_COMMAND_REMOVE_PARENT_ID, -} process_command_type_t; - -typedef enum _notify_command_type { - NOTIFY_COMMAND_SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT, - NOTIFY_COMMAND_CHANGE_ROUTE_START_WITH_NEW_DATA, - NOTIFY_COMMAND_CHANGE_ROUTE_START, - NOTIFY_COMMAND_CHANGE_ROUTE_END, - NOTIFY_COMMAND_UPDATE_ROUTE_OPTION, - NOTIFY_COMMAND_INFORM_STREAM_CONNECTED, - NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED, -} notify_command_type_t; - -const char* process_command_type_str[] = { - "PREPARE", - "CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA", - "CHANGE_ROUTE_BY_STREAM_STARTED", - "CHANGE_ROUTE_BY_STREAM_ENDED", - "CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED", - "UPDATE_VOLUME", - "ADD_PARENT_ID", - "REMOVE_PARENT_ID", -}; - -const char* notify_command_type_str[] = { - "SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT", - "CHANGE_ROUTE_START_WITH_NEW_DATA", - "CHANGE_ROUTE_START", - "CHANGE_ROUTE_END", - "UPDATE_ROUTE_OPTION", - "INFORM_STREAM_CONNECTED", - "INFORM_STREAM_DISCONNECTED", -}; - -#define STREAM_MAP_FILE "/etc/pulse/stream-map.json" -#define STREAM_MAP_VOLUMES "volumes" -#define STREAM_MAP_VOLUME_TYPE "type" -#define STREAM_MAP_VOLUME_IS_FOR_HAL "is-hal-volume" -#define STREAM_MAP_STREAMS "streams" -#define STREAM_MAP_STREAM_ROLE "role" -#define STREAM_MAP_STREAM_PRIORITY "priority" -#define STREAM_MAP_STREAM_ROUTE_TYPE "route-type" -#define STREAM_MAP_STREAM_DIRECTIONS "directions" -#define STREAM_MAP_STREAM_VOLUME_TYPES "volume-types" -#define STREAM_MAP_STREAM_VOLUME_TYPE_IN "in" -#define STREAM_MAP_STREAM_VOLUME_TYPE_OUT "out" -#define STREAM_MAP_STREAM_CAPTURE_VOLUME_TYPE "capture-volume-type" -#define STREAM_MAP_STREAM_PLAYBACK_VOLUME_TYPE "playback-volume-type" -#define STREAM_MAP_STREAM_AVAIL_IN_DEVICES "avail-in-devices" -#define STREAM_MAP_STREAM_AVAIL_OUT_DEVICES "avail-out-devices" -#define STREAM_MAP_STREAM_AVAIL_FRAMEWORKS "avail-frameworks" - -typedef struct _stream_parent { - pa_idxset *idx_sink_inputs; - pa_idxset *idx_source_outputs; - pa_idxset *idx_route_in_devices; - pa_idxset *idx_route_out_devices; - focus_acquired_status_t focus_status; -} stream_parent; - -#define AVAIL_DEVICES_MAX 16 -#define AVAIL_FRAMEWORKS_MAX 16 -#define AVAIL_STREAMS_MAX 32 -typedef struct _stream_info_per_type { - int32_t priority; - int32_t route_type; - int32_t num_of_in_devices; - int32_t num_of_out_devices; - int32_t num_of_frameworks; - char *avail_in_devices[AVAIL_DEVICES_MAX]; - char *avail_out_devices[AVAIL_DEVICES_MAX]; - char *avail_frameworks[AVAIL_FRAMEWORKS_MAX]; -} stream_info_per_type; -typedef struct _stream_list { - int32_t num_of_streams; - char* types[AVAIL_STREAMS_MAX]; - int32_t priorities[AVAIL_STREAMS_MAX]; -} stream_list; -typedef struct _stream_route_option { - const char *name; - int32_t value; -} stream_route_option; - -static void do_notify(pa_stream_manager *m, notify_command_type_t command, stream_type_t type, void *user_data); -static process_stream_result_t process_stream(stream_type_t type, void *stream, process_command_type_t command, pa_stream_manager *m); - -static int get_available_streams(pa_stream_manager *m, stream_list *list) { - void *state = NULL; - stream_info *s = NULL; - char *role = NULL; - int i = 0; - - pa_log_info("get_available_streams"); - if (m->stream_infos) { - while ((s = pa_hashmap_iterate(m->stream_infos, &state, (const void**)&role))) { - if (i < AVAIL_STREAMS_MAX) { - list->priorities[i] = s->priority; - list->types[i++] = role; - pa_log_debug(" [%d] stream_type[%s], priority[%d]", i-1, role, s->priority); - } else { - pa_log_error(" out of range, [%d]", i); - break; - } - } - list->num_of_streams = i; - pa_log_debug(" num_of_streams[%d]",i); - } else { - pa_log_error("stream_map is not initialized.."); - return -1; - } - return 0; -} - -static int get_stream_info(pa_stream_manager *m, const char *stream_role, stream_info_per_type *info) { - uint32_t idx = 0; - char *name; - stream_info *s = NULL; - int i = 0; - int j = 0; - int k = 0; - pa_log_info("get_stream_info : role[%s]", stream_role); - if (m->stream_infos) { - s = pa_hashmap_get(m->stream_infos, stream_role); - if (s) { - info->priority = s->priority; - info->route_type = s->route_type; - PA_IDXSET_FOREACH(name, s->idx_avail_in_devices, idx) { - pa_log_debug(" avail-in-device[%d] name : %s", i, name); - if (i < AVAIL_DEVICES_MAX) - info->avail_in_devices[i++] = name; - else - pa_log_error(" avail-in-devices, out of range, [%d]", i); - } - info->num_of_in_devices = i; - PA_IDXSET_FOREACH(name, s->idx_avail_out_devices, idx) { - pa_log_debug(" avail-out-device[%d] name : %s", j, name); - if (j < AVAIL_DEVICES_MAX) - info->avail_out_devices[j++] = name; - else - pa_log_error(" avail-out-devices, out of range, [%d]", j); - } - info->num_of_out_devices = j; - PA_IDXSET_FOREACH(name, s->idx_avail_frameworks, idx) { - pa_log_debug(" avail-frameworks[%d] name : %s", k, name); - if (k < AVAIL_FRAMEWORKS_MAX) - info->avail_frameworks[k++] = name; - else - pa_log_error(" avail-frameworks, out of range, [%d]", k); - } - info->num_of_frameworks = k; - } - } else { - pa_log_error("stream_map is not initialized.."); - return -1; - } - return 0; -} - -#ifdef HAVE_DBUS -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *xml = STREAM_MGR_INTROSPECT_XML; - DBusMessage *r = NULL; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se(r = dbus_message_new_method_return(msg)); - pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)); - - if (r) { - pa_assert_se(dbus_connection_send((conn), r, NULL)); - dbus_message_unref(r); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void handle_get_stream_list(DBusConnection *conn, DBusMessage *msg, void *userdata) { - stream_list list; - DBusMessage *reply = NULL; - DBusMessageIter msg_iter; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INVALID)); - pa_log_info("handle_get_stream_list() dbus method is called"); - - memset(&list, 0, sizeof(stream_list)); - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dbus_message_iter_init_append(reply, &msg_iter); - if(!get_available_streams(m, &list)) { - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, &list.types, list.num_of_streams); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_INT32, &list.priorities, list.num_of_streams); - } else { - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, NULL, 0); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_INT32, NULL, 0); - } - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_get_stream_info(DBusConnection *conn, DBusMessage *msg, void *userdata) { - char *type; - stream_info_per_type info; - DBusMessage *reply = NULL; - DBusMessageIter msg_iter; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_INVALID)); - pa_log_info("handle_get_stream_info(), type[%s]", type); - - memset(&info, 0, sizeof(stream_info_per_type)); - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dbus_message_iter_init_append(reply, &msg_iter); - if(!get_stream_info(m, type, &info)) { - pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_INT32, &info.priority); - pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_INT32, &info.route_type); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, &info.avail_in_devices, info.num_of_in_devices); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, &info.avail_out_devices, info.num_of_out_devices); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, &info.avail_frameworks, info.num_of_frameworks); - } else { - pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_INT32, 0); - pa_dbus_append_basic_variant(&msg_iter, DBUS_TYPE_INT32, 0); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, NULL, 0); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, NULL, 0); - pa_dbus_append_basic_array_variant(&msg_iter, DBUS_TYPE_STRING, NULL, 0); - } - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_set_stream_route_devices(DBusConnection *conn, DBusMessage *msg, void *userdata) { - uint32_t id = 0; - int i = 0; - uint32_t *in_device_list = NULL; - uint32_t *out_device_list = NULL; - int list_len_in = 0; - int list_len_out = 0; - uint32_t idx = 0; - uint32_t *device_id = NULL; - stream_parent *sp = NULL; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_UINT32, &id, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &in_device_list, &list_len_in, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &out_device_list, &list_len_out, - DBUS_TYPE_INVALID)); - pa_log_info("handle_set_stream_route_devices(), id[%u], in_device_list[%p]:length[%d], out_device_list[%p]:length[%d]", - id, in_device_list, list_len_in, out_device_list, list_len_out); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - sp = pa_hashmap_get(m->stream_parents, (const void*)id); - if (sp) { - if (!in_device_list && !out_device_list) { - pa_log_error("invalid arguments"); - goto FAILURE; - } - - if (sp->idx_route_in_devices) { - PA_IDXSET_FOREACH(device_id, sp->idx_route_in_devices, idx) { - pa_idxset_remove_by_data(sp->idx_route_in_devices, device_id, NULL); - pa_xfree(device_id); - } - if (in_device_list && list_len_in) { - for (i = 0; i < list_len_in; i++) { - pa_idxset_put(sp->idx_route_in_devices, pa_xmemdup(&in_device_list[i], sizeof(uint32_t)), NULL); - pa_log_debug(" -- [in] device id:%u", in_device_list[i]); - } - } - if (m->cur_highest_priority.source_output) { - /* if any stream that belongs to this id has been activated, do notify right away */ - if (pa_idxset_get_by_data(sp->idx_source_outputs, m->cur_highest_priority.source_output, NULL)) { - pa_log_debug(" -- cur_highest_priority.source_output->index[%u] belongs to this parent id[%u], do notify for the route change", - (m->cur_highest_priority.source_output)->index, id); - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, m->cur_highest_priority.source_output); - } - } - } else { - pa_log_error("failed to update, idx_route_in_devices[%p]", sp->idx_route_in_devices); - goto FAILURE; - } - - if (sp->idx_route_out_devices) { - PA_IDXSET_FOREACH(device_id, sp->idx_route_out_devices, idx) { - pa_idxset_remove_by_data(sp->idx_route_out_devices, device_id, NULL); - pa_xfree(device_id); - } - if (out_device_list && list_len_out) { - for (i = 0; i < list_len_out; i++) { - pa_idxset_put(sp->idx_route_out_devices, pa_xmemdup(&out_device_list[i], sizeof(uint32_t)), NULL); - pa_log_debug(" -- [out] device id:%u", out_device_list[i]); - } - } - if (m->cur_highest_priority.sink_input) { - /* if any stream that belongs to this id has been activated, do notify right away */ - if (pa_idxset_get_by_data(sp->idx_sink_inputs, m->cur_highest_priority.sink_input, NULL)) { - pa_log_debug(" -- cur_highest_priority.sink_input->index[%u] belongs to this parent id[%u], do notify for the route change", - (m->cur_highest_priority.sink_input)->index, id); - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, m->cur_highest_priority.sink_input); - } - } - } else { - pa_log_error("failed to update, idx_route_out_devices[%p]", sp->idx_route_out_devices); - goto FAILURE; - } - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - } else { - pa_log_error("could not find matching client for this parent_id[%u]", id); - goto FAILURE; - } - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -FAILURE: - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static void handle_set_stream_route_option(DBusConnection *conn, DBusMessage *msg, void *userdata) { - uint32_t id = 0; - const char *name = NULL; - int32_t value = 0; - pa_bool_t updated = FALSE; - stream_parent *sp = NULL; - stream_route_option route_option; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_UINT32, &id, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INT32, &value, - DBUS_TYPE_INVALID)); - pa_log_info("handle_set_stream_route_option(), name[%s], value[%d]", name, value); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - sp = pa_hashmap_get(m->stream_parents, (const void*)id); - if (sp) { - if (name) { - route_option.name = name; - route_option.value = value; - - /* if any stream that belongs to this id has been activated, do notify right away */ - if (m->cur_highest_priority.sink_input) { - if (pa_idxset_get_by_data(sp->idx_sink_inputs, m->cur_highest_priority.sink_input, NULL)) { - pa_log_debug(" -- cur_highest_priority.sink_input->index[%u] belongs to this parent id[%u], do notify for the options", - (m->cur_highest_priority.sink_input)->index, id); - do_notify(m, NOTIFY_COMMAND_UPDATE_ROUTE_OPTION, STREAM_SINK_INPUT, &route_option); - updated = TRUE; - } - } - if (m->cur_highest_priority.source_output) { - if (pa_idxset_get_by_data(sp->idx_source_outputs, m->cur_highest_priority.source_output, NULL)) { - pa_log_debug(" -- cur_highest_priority.source_output->index[%u] belongs to this parent id[%u], do notify for the options", - (m->cur_highest_priority.source_output)->index, id); - do_notify(m, NOTIFY_COMMAND_UPDATE_ROUTE_OPTION, STREAM_SOURCE_OUTPUT, &route_option); - updated = TRUE; - } - } - if (!updated) { - pa_log_error("invalid state"); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR_NO_STREAM], DBUS_TYPE_INVALID)); - } else - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - } else { - pa_log_error("invalid arguments"); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - } - - } else { - pa_log_error("could not find matching client for this parent_id[%u]", id); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - } - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static void send_volume_changed_signal(DBusConnection *conn, const char *direction, const char *volume_type, const uint32_t volume_level) { - DBusMessage *signal_msg; - DBusMessageIter msg_iter; - - pa_assert(conn); - pa_assert(volume_type); - - pa_log_debug("Send volume changed signal : direction %s, type %s, level %d", direction, volume_type, volume_level); - - pa_assert_se(signal_msg = dbus_message_new_signal(STREAM_MANAGER_OBJECT_PATH, STREAM_MANAGER_INTERFACE, "VolumeChanged")); - dbus_message_iter_init_append(signal_msg, &msg_iter); - - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &direction); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &volume_type); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_UINT32, &volume_level); - - pa_assert_se(dbus_connection_send(conn, signal_msg, NULL)); - dbus_message_unref(signal_msg); - return; -} - -static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *direction = NULL; - const char *type = NULL; - uint32_t level = 0; - stream_type_t stream_type = STREAM_SINK_INPUT; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - int ret = 0; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &direction, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_UINT32, &level, - DBUS_TYPE_INVALID)); - pa_log_info("handle_set_volume_level(), direction[%s], type[%s], level[%u]", direction, type, level); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - if (pa_streq(direction, "in")) - stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) - stream_type = STREAM_SINK_INPUT; - else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; - } - - if ((ret = set_volume_level_by_type(m, stream_type, type, level))) - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - else - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - -FAILURE: - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - - if (!ret) - send_volume_changed_signal(conn, direction, type, level); - return; -} - -static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *direction = NULL; - const char *type = NULL; - uint32_t level = 0; - stream_type_t stream_type = STREAM_SINK_INPUT; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &direction, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_INVALID)); - pa_log_info("handle_get_volume_level(), direction(%s), type(%s)", direction, type); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - if (pa_streq(direction, "in")) - stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) - stream_type = STREAM_SINK_INPUT; - else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; - } - - if (get_volume_level_by_type(m, GET_VOLUME_CURRENT_LEVEL, stream_type, type, &level)) { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - } else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &level, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - } - -FAILURE: - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *direction = NULL; - const char *type = NULL; - uint32_t level = 0; - stream_type_t stream_type = STREAM_SINK_INPUT; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &direction, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_INVALID)); - pa_log_info("handle_get_volume_max_level(), direction[%s], type[%s]", direction, type); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - if (pa_streq(direction, "in")) - stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) - stream_type = STREAM_SINK_INPUT; - else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; - } - - if (get_volume_level_by_type(m, GET_VOLUME_MAX_LEVEL, stream_type, type, &level)) { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - } else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &level, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - } -FAILURE: - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *direction = NULL; - const char *type = NULL; - uint32_t do_mute = 0; - stream_type_t stream_type = STREAM_SINK_INPUT; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &direction, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_UINT32, &do_mute, - DBUS_TYPE_INVALID)); - pa_log_info("handle_set_volume_mute(), direction[%s], type[%s], do_mute[%u]", direction, type, do_mute); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - if (pa_streq(direction, "in")) - stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) - stream_type = STREAM_SINK_INPUT; - else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; - } - - if (set_volume_mute_by_type(m, stream_type, type, (pa_bool_t)do_mute)) - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - else - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - -FAILURE: - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *direction = NULL; - const char *type = NULL; - uint32_t is_muted = 0; - stream_type_t stream_type = STREAM_SINK_INPUT; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &direction, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_INVALID)); - pa_log_info("handle_get_volume_mute(), direction[%s], type[%s]", direction, type); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - if (pa_streq(direction, "in")) - stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) - stream_type = STREAM_SINK_INPUT; - else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; - } - - if (get_volume_mute_by_type(m, stream_type, type, (pa_bool_t*)&is_muted)) { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - } else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &is_muted, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - } - -FAILURE: - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *direction = NULL; - const char *type = NULL; - void *s = NULL; - stream_type_t stream_type = STREAM_SINK_INPUT; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &direction, - DBUS_TYPE_INVALID)); - pa_log_info("handle_get_current_volume_type(), direction[%s]", direction); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - if (pa_streq(direction, "in")) - stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) - stream_type = STREAM_SINK_INPUT; - else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &dbus_str_none, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; - } - - s = (stream_type == STREAM_SINK_INPUT)?(void*)(m->cur_highest_priority.sink_input):(void*)(m->cur_highest_priority.source_output); - if (s) { - type = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &type, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); - } else { - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &dbus_str_none, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR_NO_STREAM], DBUS_TYPE_INVALID)); - } - -FAILURE: - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata) { - uint32_t id = 0; - uint32_t idx = 0; - uint32_t count = 0; - uint32_t acquired_focus_status = 0; - stream_parent *sp = NULL; - void *stream = NULL; - DBusMessage *reply = NULL; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_UINT32, &id, - DBUS_TYPE_UINT32, &acquired_focus_status, - DBUS_TYPE_INVALID)); - pa_log_info("handle_update_focus_status(), id[%u], acquired_focus_status[0x%x]", id, acquired_focus_status); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - sp = pa_hashmap_get(m->stream_parents, (const void*)id); - if (sp) { - if (sp->focus_status != (acquired_focus_status & (STREAM_FOCUS_ACQUIRED_PLAYBACK|STREAM_FOCUS_ACQUIRED_CAPTURE))) { - /* need to update */ - sp->focus_status = acquired_focus_status & (STREAM_FOCUS_ACQUIRED_PLAYBACK|STREAM_FOCUS_ACQUIRED_CAPTURE); - if (sp->idx_sink_inputs) - count = pa_idxset_size(sp->idx_sink_inputs); - PA_IDXSET_FOREACH(stream, sp->idx_sink_inputs, idx) { - pa_proplist_sets(GET_STREAM_PROPLIST(stream, STREAM_SINK_INPUT), PA_PROP_MEDIA_FOCUS_STATUS, - IS_FOCUS_ACQUIRED(sp->focus_status, STREAM_SINK_INPUT)?STREAM_FOCUS_PLAYBACK:STREAM_FOCUS_NONE); - if (--count == 0) - process_stream(STREAM_SINK_INPUT, stream, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED, m); - } - if (sp->idx_source_outputs) - count = pa_idxset_size(sp->idx_source_outputs); - PA_IDXSET_FOREACH(stream, sp->idx_source_outputs, idx) { - pa_proplist_sets(GET_STREAM_PROPLIST(stream, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_FOCUS_STATUS, - IS_FOCUS_ACQUIRED(sp->focus_status, STREAM_SOURCE_OUTPUT)?STREAM_FOCUS_CAPTURE:STREAM_FOCUS_NONE); - if (--count == 0) - process_stream(STREAM_SOURCE_OUTPUT, stream, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED, m); - } - } else - pa_log_debug("same as before, skip updating focus status[0x%x]", acquired_focus_status); - - } else { - pa_log_error("could not find matching client for this parent_id[%u]", id); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); - goto FAILURE; - } - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID)); -FAILURE: - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; -} - -static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) { - int idx = 0; - pa_stream_manager *m = (pa_stream_manager*)userdata; - - pa_assert(conn); - pa_assert(msg); - pa_assert(m); - - for (idx = 0; idx < METHOD_HANDLER_MAX; idx++) { - if (dbus_message_is_method_call(msg, STREAM_MANAGER_INTERFACE, method_handlers[idx].method_name )) { - pa_log_debug("Message signature [%s] (Expected [%s])", dbus_message_get_signature(msg), signature_args_for_in[idx]); - if (pa_streq(dbus_message_get_signature(msg), signature_args_for_in[idx])) { - method_handlers[idx].receive_cb(conn, msg, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } else { - pa_log_warn("Wrong Argument Signature"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_SIGNATURE, "Wrong Signature, Expected %s", signature_args_for_in[idx]); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - } - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m, void *userdata) { - pa_stream_manager *u = (pa_stream_manager*)userdata; - const char *path, *interface, *member; - - pa_assert(c); - pa_assert(m); - pa_assert(u); - - path = dbus_message_get_path(m); - interface = dbus_message_get_interface(m); - member = dbus_message_get_member(m); - - pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member); - - if (!pa_streq(path, STREAM_MANAGER_OBJECT_PATH)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { - return handle_introspect(c, m, u); - } else { - return handle_methods(c, m, u); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} -#endif - -static int convert_route_type(stream_route_type_t *route_type, const char *route_type_string) { - int ret = 0; - - pa_assert(route_type); - pa_assert(route_type_string); - - if (pa_streq("auto", route_type_string)) - *route_type = STREAM_ROUTE_TYPE_AUTO; - else if (pa_streq("auto-all", route_type_string)) - *route_type = STREAM_ROUTE_TYPE_AUTO_ALL; - else if (pa_streq("manual", route_type_string)) - *route_type = STREAM_ROUTE_TYPE_MANUAL; - else { - ret = -1; - pa_log_error("Not supported route_type(%s)", route_type_string); - } - - return ret; -} - -static void dump_stream_map (pa_stream_manager *m) { - stream_info *s = NULL; - const char *role = NULL; - char *name = NULL; - void *state = NULL; - uint32_t idx = 0; - pa_assert(m); - pa_log_debug("==========[START stream-map dump]=========="); - while (m->stream_infos && (s = pa_hashmap_iterate(m->stream_infos, &state, (const void **)&role))) { - pa_log_debug("[role : %s]", role); - pa_log_debug(" - priority : %d", s->priority); - pa_log_debug(" - route-type : %d (0:auto,1:auto-all,2:manual)", s->route_type); - pa_log_debug(" - volume-types : in[%s], out[%s]", s->volume_type[STREAM_DIRECTION_IN], s->volume_type[STREAM_DIRECTION_OUT]); - pa_log_debug(" - avail-in-devices"); - PA_IDXSET_FOREACH(name, s->idx_avail_in_devices, idx) - pa_log_debug(" name[%d] : %s", idx, name); - pa_log_debug(" - avail-out-devices"); - PA_IDXSET_FOREACH(name, s->idx_avail_out_devices, idx) - pa_log_debug(" name[%d] : %s", idx, name); - pa_log_debug(" - avail-frameworks"); - PA_IDXSET_FOREACH(name, s->idx_avail_frameworks, idx) - pa_log_debug(" name[%d] : %s", idx, name); - } - pa_log_debug("===========[END stream-map dump]==========="); - return; -} - -static int init_stream_map (pa_stream_manager *m) { - volume_info *v; - stream_info *s; - json_object *o; - json_object *volume_array_o; - json_object *stream_array_o; - json_object *volume_type_o; - json_object *is_hal_volume_o; - json_object *role_o; - json_object *priority_o; - json_object *route_type_o; - json_object *volume_types_o; - json_object *avail_in_devices_o; - json_object *avail_out_devices_o; - json_object *avail_frameworks_o; - int num_of_volume_types = 0; - int num_of_stream_types = 0; - const char *volume_type = NULL; - const char *role = NULL; - int i = 0, j = 0; - int num_of_avail_in_devices; - int num_of_avail_out_devices; - int num_of_avail_frameworks; - json_object *out_device_o; - json_object *in_device_o; - json_object *framework_o; - json_object *volume_o; - json_object *stream_o; - const char *volume_type_in_str = NULL; - const char *volume_type_out_str = NULL; - json_object *volume_type_in_o; - json_object *volume_type_out_o; - void *state = NULL; - - pa_assert(m); - - o = json_object_from_file(STREAM_MAP_FILE); - if(is_error(o)) { - pa_log_error("Read stream-map file(%s) failed", STREAM_MAP_FILE); - return -1; - } - - /* Volumes */ - m->volume_infos = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if((volume_array_o = json_object_object_get(o, STREAM_MAP_VOLUMES)) && json_object_is_type(volume_array_o, json_type_array)) { - num_of_volume_types = json_object_array_length(volume_array_o); - for (i = 0; i < num_of_volume_types; i++) { - if((volume_o = json_object_array_get_idx(volume_array_o, i)) && json_object_is_type(volume_o, json_type_object)) { - v = pa_xmalloc0(sizeof(volume_info)); - pa_log_debug("volume found [%d]", i); - if((volume_type_o = json_object_object_get(volume_o, STREAM_MAP_VOLUME_TYPE)) && json_object_is_type(volume_type_o, json_type_string)) { - volume_type = json_object_get_string(volume_type_o); - pa_log_debug(" - type : %s", volume_type); - } else { - pa_log_error("Get volume type failed"); - goto failed; - } - if((is_hal_volume_o = json_object_object_get(volume_o, STREAM_MAP_VOLUME_IS_FOR_HAL)) && json_object_is_type(is_hal_volume_o, json_type_int)) { - v->is_hal_volume_type = (pa_bool_t)json_object_get_int(is_hal_volume_o); - pa_log_debug(" - is-hal-volume : %d", v->is_hal_volume_type); - } else { - pa_log_error("Get is-hal-volume failed"); - goto failed; - } - } - pa_hashmap_put(m->volume_infos,(void*)volume_type, v); - } - } - - /* Streams */ - m->stream_infos = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - if((stream_array_o = json_object_object_get(o, STREAM_MAP_STREAMS)) && json_object_is_type(stream_array_o, json_type_array)) { - num_of_stream_types = json_object_array_length(stream_array_o); - for (i = 0; i < num_of_stream_types; i++) { - - if((stream_o = json_object_array_get_idx(stream_array_o, i)) && json_object_is_type(stream_o, json_type_object)) { - s = pa_xmalloc0(sizeof(stream_info)); - pa_log_debug("stream found [%d]", i); - if((role_o = json_object_object_get(stream_o, STREAM_MAP_STREAM_ROLE)) && json_object_is_type(role_o, json_type_string)) { - role = json_object_get_string(role_o); - pa_log_debug(" - role : %s", role); - } else { - pa_log_error("Get stream role failed"); - goto failed; - } - if((priority_o = json_object_object_get(stream_o, STREAM_MAP_STREAM_PRIORITY)) && json_object_is_type(priority_o, json_type_int)) { - s->priority = json_object_get_int(priority_o); - pa_log_debug(" - priority : %d", s->priority); - } else { - pa_log_error("Get stream priority failed"); - goto failed; - } - if((route_type_o = json_object_object_get(stream_o, STREAM_MAP_STREAM_ROUTE_TYPE)) && json_object_is_type(route_type_o, json_type_string)) { - if (convert_route_type(&(s->route_type), json_object_get_string(route_type_o))) { - pa_log_error("convert stream route-type failed"); - goto failed; - } - pa_log_debug(" - route-type : %d", s->route_type); - } else { - pa_log_error("Get stream route-type failed"); - goto failed; - } - if((volume_types_o = json_object_object_get(stream_o, STREAM_MAP_STREAM_VOLUME_TYPES)) && json_object_is_type(volume_types_o, json_type_object)) { - if((volume_type_in_o = json_object_object_get(volume_types_o, STREAM_MAP_STREAM_VOLUME_TYPE_IN)) && json_object_is_type(volume_type_in_o, json_type_string)) { - volume_type_in_str = json_object_get_string(volume_type_in_o); - if (!pa_streq(volume_type_in_str, "none")) - s->volume_type[STREAM_DIRECTION_IN] = volume_type_in_str; - } else { - pa_log_error("Get stream volume-type-in failed"); - goto failed; - } - if((volume_type_out_o = json_object_object_get(volume_types_o, STREAM_MAP_STREAM_VOLUME_TYPE_OUT)) && json_object_is_type(volume_type_out_o, json_type_string)) { - volume_type_out_str = json_object_get_string(volume_type_out_o); - if (!pa_streq(volume_type_out_str, "none")) - s->volume_type[STREAM_DIRECTION_OUT] = volume_type_out_str; - } else { - pa_log_error("Get stream volume-type-out failed"); - goto failed; - } - pa_log_debug(" - volume-types : in[%s], out[%s]", s->volume_type[STREAM_DIRECTION_IN], s->volume_type[STREAM_DIRECTION_OUT]); - } else { - pa_log_error("Get stream volume-types failed"); - goto failed; - } - if((avail_in_devices_o = json_object_object_get(stream_o, STREAM_MAP_STREAM_AVAIL_IN_DEVICES)) && json_object_is_type(avail_in_devices_o, json_type_array)) { - j = 0; - s->idx_avail_in_devices = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - num_of_avail_in_devices = json_object_array_length(avail_in_devices_o); - pa_log_debug(" - avail-in-devices"); - for (j = 0; j < num_of_avail_in_devices; j++) { - if((in_device_o = json_object_array_get_idx(avail_in_devices_o, j)) && json_object_is_type(in_device_o, json_type_string)) { - pa_idxset_put(s->idx_avail_in_devices, (void*)json_object_get_string(in_device_o), NULL); - pa_log_debug(" device[%d] : %s", j, json_object_get_string(in_device_o)); - } - } - } else { - pa_log_error("Get stream avail-in-devices failed"); - goto failed; - } - if((avail_out_devices_o = json_object_object_get(stream_o, STREAM_MAP_STREAM_AVAIL_OUT_DEVICES)) && json_object_is_type(avail_out_devices_o, json_type_array)) { - j = 0; - s->idx_avail_out_devices = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - num_of_avail_out_devices = json_object_array_length(avail_out_devices_o); - pa_log_debug(" - avail-out-devices"); - for (j = 0; j < num_of_avail_out_devices; j++) { - if((out_device_o = json_object_array_get_idx(avail_out_devices_o, j)) && json_object_is_type(out_device_o, json_type_string)) { - pa_idxset_put(s->idx_avail_out_devices, (void*)json_object_get_string(out_device_o), NULL); - pa_log_debug(" device[%d] : %s", j, json_object_get_string(out_device_o)); - } - } - } else { - pa_log_error("Get stream avail-out-devices failed"); - goto failed; - } - if((avail_frameworks_o = json_object_object_get(stream_o, STREAM_MAP_STREAM_AVAIL_FRAMEWORKS)) && json_object_is_type(avail_frameworks_o, json_type_array)) { - j = 0; - s->idx_avail_frameworks = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - num_of_avail_frameworks = json_object_array_length(avail_frameworks_o); - pa_log_debug(" - avail-frameworks"); - for (j = 0; j < num_of_avail_frameworks; j++) { - if((framework_o = json_object_array_get_idx(avail_frameworks_o, j)) && json_object_is_type(framework_o, json_type_string)) { - pa_idxset_put(s->idx_avail_frameworks, (void*)json_object_get_string(framework_o), NULL); - pa_log_debug(" framework[%d] : %s", j, json_object_get_string(framework_o)); - } - } - } else { - pa_log_error("Get stream avail-frameworks failed"); - goto failed; - } - pa_hashmap_put(m->stream_infos,(void*)role, s); - } - } - } else { - pa_log_error("Get streams object failed"); - goto failed; - } - - dump_stream_map(m); - - return 0; -failed: - pa_log_error("Failed to initialize stream-map"); - if (m->stream_infos) { - PA_HASHMAP_FOREACH(s, m->stream_infos, state) { - if (s->idx_avail_in_devices) - pa_idxset_free(s->idx_avail_in_devices, NULL); - if (s->idx_avail_out_devices) - pa_idxset_free(s->idx_avail_out_devices, NULL); - if (s->idx_avail_frameworks) - pa_idxset_free(s->idx_avail_frameworks, NULL); - pa_xfree(s); - } - pa_hashmap_free(m->stream_infos); - } - if (m->volume_infos) { - PA_HASHMAP_FOREACH(v, m->volume_infos, state) { - pa_xfree(v); - } - pa_hashmap_free(m->volume_infos); - } - return -1; -} - -static void deinit_stream_map (pa_stream_manager *m) { - stream_info *s = NULL; - volume_info *v = NULL; - void *state = NULL; - pa_assert(m); - - if (m->stream_infos) { - PA_HASHMAP_FOREACH(s, m->stream_infos, state) { - if (s->idx_avail_in_devices) - pa_idxset_free(s->idx_avail_in_devices, NULL); - if (s->idx_avail_out_devices) - pa_idxset_free(s->idx_avail_out_devices, NULL); - if (s->idx_avail_frameworks) - pa_idxset_free(s->idx_avail_frameworks, NULL); - pa_xfree(s); - } - pa_hashmap_free(m->stream_infos); - } - if (m->volume_infos) { - PA_HASHMAP_FOREACH(v, m->volume_infos, state) { - pa_xfree(v); - } - pa_hashmap_free(m->volume_infos); - } - - return; -} - -static pa_bool_t check_name_to_skip(pa_stream_manager *m, process_command_type_t command, stream_type_t type, void *stream) { - pa_bool_t ret = FALSE; - const char *name = NULL; - const char *role = NULL; - int i = 0; - - pa_assert(m); - pa_assert(stream); - - if (command == PROCESS_COMMAND_PREPARE) { - name = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_NAME); - if (name) { - for (i = 0; i < NAME_FOR_SKIP_MAX; i++) - if (pa_streq(name, stream_manager_media_names_for_skip[i])) { - ret = TRUE; - pa_proplist_sets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE, SKIP_ROLE); - break; - } - pa_log_info("name is [%s], skip(%d)", name, ret); - } - } else { - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA || - command == PROCESS_COMMAND_UPDATE_VOLUME) - role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - else - role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - - if (role && pa_streq(role, "skip")) - ret = TRUE; - } - - return ret; -} - -static pa_bool_t check_role_to_skip(pa_stream_manager *m, const char *role) { - pa_bool_t ret = TRUE; - stream_info *s = NULL; - - pa_assert(m); - pa_assert(role); - - if (m->stream_infos) { - s = pa_hashmap_get(m->stream_infos, role); - if (s) - ret = FALSE; - } - - pa_log_info("role is [%s], skip(%d)", role, ret); - - return ret; -} - -static pa_bool_t update_priority_of_stream(pa_stream_manager *m, process_command_type_t command, stream_type_t type, void *stream, const char *role) { - stream_info *s = NULL; - - pa_assert(m); - pa_assert(role); - - if (m->stream_infos) - s = pa_hashmap_get(m->stream_infos, role); - else - return FALSE; - - if (s) { - if (command == PROCESS_COMMAND_PREPARE) - pa_proplist_set(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void*)&(s->priority), sizeof(s->priority)); - else - pa_proplist_set(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void*)&(s->priority), sizeof(s->priority)); - } - - return TRUE; -} - -static pa_bool_t update_routing_type_of_stream(pa_stream_manager *m, void *stream, stream_type_t type, const char *role) { - stream_route_type_t route_type = STREAM_ROUTE_TYPE_AUTO; - stream_info *s = NULL; - - pa_assert(m); - pa_assert(role); - - if (m->stream_infos) { - s = pa_hashmap_get(m->stream_infos, role); - if (s) - route_type = s->route_type; - } else - return FALSE; - - pa_proplist_setf(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_ROUTE_TYPE, "%d", route_type); - - return TRUE; -} - -static pa_bool_t update_volume_type_of_stream(pa_stream_manager *m, stream_type_t type, void *stream, const char *role) { - const char *volume_type = NULL; - stream_info *s = NULL; - - pa_assert(m); - pa_assert(role); - - if (m->stream_infos) { - s = pa_hashmap_get(m->stream_infos, role); - if (s) - volume_type = s->volume_type[!type]; - } else - return FALSE; - - if (volume_type) - pa_proplist_sets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, volume_type); - else - pa_log_warn("this stream[%p] does not have any volume type, skip updating volume type. stream_type[%d], role[%s]", stream, type, role); - - return TRUE; -} - -static pa_bool_t update_focus_status_of_stream(pa_stream_manager *m, process_command_type_t command, void *stream, stream_type_t type) { - const char *p_idx; - uint32_t parent_idx; - stream_parent *sp = NULL; - - pa_assert(m); - pa_assert(stream); - - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA) - p_idx = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_PARENT_ID); - else - p_idx = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_PARENT_ID); - if (p_idx && !pa_atou(p_idx, &parent_idx)) { - pa_log_debug("p_idx(%s), idx(%u)", p_idx, parent_idx); - sp = pa_hashmap_get(m->stream_parents, (const void*)parent_idx); - if (sp) { - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA) - pa_proplist_setf(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_FOCUS_STATUS, "%u", sp->focus_status); - else - pa_proplist_setf(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_FOCUS_STATUS, "%u", sp->focus_status); - } else { - pa_log_error("could not find matching client for this parent_id(%u)", parent_idx); - return FALSE; - } - } else { - pa_log_warn("p_idx(%s) or idx(%u) is not valid", p_idx, parent_idx); - return FALSE; - } - - return TRUE; -} - -static pa_bool_t update_stream_parent_info(pa_stream_manager *m, process_command_type_t command, stream_type_t type, void *stream) { - const char *p_idx; - uint32_t parent_idx; - stream_parent *sp = NULL; - - pa_assert(m); - pa_assert(stream); - - p_idx = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_PARENT_ID); - if (p_idx && !pa_atou(p_idx, &parent_idx)) { - pa_log_debug("p_idx(%s), idx(%u)", p_idx, parent_idx); - sp = pa_hashmap_get(m->stream_parents, (const void*)parent_idx); - if (sp) { - uint32_t idx = (type==STREAM_SINK_INPUT)?((pa_sink_input*)stream)->index:((pa_source_output*)stream)->index; - if (command == PROCESS_COMMAND_ADD_PARENT_ID) { - /* append this stream to the parent stream info. */ - pa_log_debug(" - append this stream(%p, %u) to the list. sp(%p), stream_type(%d)", stream, idx, sp, type); - pa_idxset_put(type==STREAM_SINK_INPUT?(sp->idx_sink_inputs):(sp->idx_source_outputs), stream, NULL); - return TRUE; - } else if (command == PROCESS_COMMAND_REMOVE_PARENT_ID) { - /* remove this stream from the parent stream info. */ - pa_log_debug(" - remove this stream(%p, %u) from the list. sp(%p), stream_type(%d)", stream, idx, sp, type); - pa_idxset_remove_by_data(type==STREAM_SINK_INPUT?(sp->idx_sink_inputs):(sp->idx_source_outputs), stream, NULL); - return TRUE; - } else { - pa_log_error("invalid command(%d)", command); - return FALSE; - } - } else { - pa_log_error("could not find matching client for this parent_id(%u)", parent_idx); - return FALSE; - } - } else { - pa_log_warn("p_idx(%s) or idx(%u) is not valid", p_idx, parent_idx); - return FALSE; - } - return TRUE; -} - -static pa_bool_t update_the_highest_priority_stream(pa_stream_manager *m, process_command_type_t command, void *mine, - stream_type_t type, const char *role, pa_bool_t *need_to_update) { - uint32_t idx = 0; - size_t size = 0; - const int32_t *priority = NULL; - const char *focus_status = NULL; - void *cur_max_stream = NULL; - void *cur_max_stream_tmp = NULL; - const int32_t *cur_max_priority = NULL; - const char *cur_max_role = NULL; - int32_t cur_max_focus_status_int = 0; - int32_t focus_status_int = 0; - void *i = NULL; - const char *_role = NULL; - pa_idxset *streams = NULL; - - pa_assert(m); - pa_assert(mine); - if (!role) { - pa_log_error("invalid input, role(%s)", role); - return FALSE; - } - - *need_to_update = FALSE; - - if (type == STREAM_SINK_INPUT) { - cur_max_stream = m->cur_highest_priority.sink_input; - } else if (type == STREAM_SOURCE_OUTPUT) { - cur_max_stream = m->cur_highest_priority.source_output; - } - - pa_log_info("update_the_highest_priority_stream(), stream_type(%d), role(%s), command(%d)", type, role, command); - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA || - command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED) { - /* get focus status */ - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA) - focus_status = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(mine, type), PA_PROP_MEDIA_FOCUS_STATUS); - else - focus_status = pa_proplist_gets(GET_STREAM_PROPLIST(mine, type), PA_PROP_MEDIA_FOCUS_STATUS); - if (focus_status && !pa_atoi(focus_status, &focus_status_int)) { - pa_log_debug("focus status(0x%x)", focus_status_int); - } - if (cur_max_stream == NULL) { - *need_to_update = TRUE; - pa_log_debug("set cur_highest to mine"); - } else { - /* TODO : need to check if this stream should be played to external devices */ - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA) { - if (pa_proplist_get(GET_STREAM_NEW_PROPLIST(mine, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&priority, &size)) - pa_log_error("Failed to pa_proplist_get() for priority"); - } else { - if (cur_max_stream == mine) { - pa_log_debug("it has already been processed, skip it.."); - return FALSE; - } - if (pa_proplist_get(GET_STREAM_PROPLIST(mine, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&priority, &size)) - pa_log_error("Failed to pa_proplist_get() for priority"); - } - if (pa_proplist_get(GET_STREAM_PROPLIST(cur_max_stream, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&cur_max_priority, &size)) - pa_log_error("Failed to pa_proplist_get() for priority"); - focus_status = pa_proplist_gets(GET_STREAM_PROPLIST(cur_max_stream, type), PA_PROP_MEDIA_FOCUS_STATUS); - if (focus_status && !pa_atoi(focus_status, &cur_max_focus_status_int)) { - pa_log_debug("cur_max_focus status(0x%x)", cur_max_focus_status_int); - } - cur_max_role = pa_proplist_gets(GET_STREAM_PROPLIST(cur_max_stream, type), PA_PROP_MEDIA_ROLE); - if (!cur_max_priority || !cur_max_role) { - pa_log_error("Failed to pa_proplist_gets() for getting current max priority(%p) and it's role(%s)", cur_max_priority, cur_max_role); - return FALSE; - } else { - if (priority && cur_max_priority) { - if (IS_FOCUS_ACQUIRED(focus_status_int, type) || - (!IS_FOCUS_ACQUIRED(cur_max_focus_status_int, type) && *priority >= *cur_max_priority)) { - *need_to_update = TRUE; - pa_log_debug("update cur_highest to mine(%s)", role); - } else { - /* no need to trigger */ - return TRUE; - } - } - } - } - } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED || - command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED) { - if (cur_max_stream == mine || command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED) { - if (type == STREAM_SINK_INPUT) { - streams = ((pa_sink_input*)mine)->sink->inputs; - } else if (type == STREAM_SOURCE_OUTPUT) { - streams = ((pa_source_output*)mine)->source->outputs; - } - /* find the next highest priority input */ - //PA_IDXSET_FOREACH(i, m->core->sinks, idx) { /* need to check a sink which this stream belongs to */ - PA_IDXSET_FOREACH(i, streams, idx) { - if (!(_role = pa_proplist_gets(GET_STREAM_PROPLIST(i, type), PA_PROP_MEDIA_ROLE))) { - pa_log_error("Failed to pa_proplist_gets() for role"); - continue; - } - if (pa_proplist_get(GET_STREAM_PROPLIST(i, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&priority, &size)) { - pa_log_warn("Failed to pa_proplist_get() for priority, skip it"); - continue; - } - if (!(focus_status = pa_proplist_gets(GET_STREAM_PROPLIST(i, type), PA_PROP_MEDIA_FOCUS_STATUS))) { - pa_log_warn("Failed to pa_proplist_gets() for focus status"); - } else { - if (!pa_atoi(focus_status, &focus_status_int)) { - pa_log_debug("focus status(0x%x)", focus_status_int); - } - } - pa_log_debug("role(%s)/priority(%p)/focus_state(0x%x)/stream(%p)", _role, priority, focus_status_int, i); - if (cur_max_priority == NULL) { - cur_max_priority = priority; - cur_max_focus_status_int = focus_status_int; - cur_max_stream_tmp = i; - } - if (cur_max_priority && priority) { - if (IS_FOCUS_ACQUIRED(cur_max_focus_status_int, type) || - (!IS_FOCUS_ACQUIRED(focus_status_int, type) && (*cur_max_priority > *priority))) { - /* skip */ - } else { - cur_max_priority = priority; - cur_max_focus_status_int = focus_status_int; - cur_max_stream_tmp = i; - } - } - } - pa_log_debug("updated max priority(%p)/stream(%p)", cur_max_priority, cur_max_stream_tmp); - if (cur_max_stream_tmp) { - if (type == STREAM_SINK_INPUT) { - m->cur_highest_priority.sink_input = cur_max_stream_tmp; - } else if (type == STREAM_SOURCE_OUTPUT) { - m->cur_highest_priority.source_output = cur_max_stream_tmp; - } - } else { - if (type == STREAM_SINK_INPUT) { - m->cur_highest_priority.sink_input = NULL; - } else if (type == STREAM_SOURCE_OUTPUT) { - m->cur_highest_priority.source_output = NULL; - } - } - *need_to_update = TRUE; - pa_log_info("need to update: type(%d), cur_highest_priority(sink_input=%p/source_output=%p)", - type, (void*)m->cur_highest_priority.sink_input, (void*)m->cur_highest_priority.sink_input); - } else { - /* no need to trigger */ - return TRUE; - } - } - return TRUE; -} - -static void fill_device_info_to_hook_data(void *hook_data, notify_command_type_t command, stream_type_t type, void *stream, pa_stream_manager *m) { - char *device_none = NULL; - const char *p_idx = NULL; - uint32_t parent_idx = 0; - stream_parent *sp = NULL; - uint32_t idx = 0; - pa_stream_manager_hook_data_for_select *select_data = NULL; - pa_stream_manager_hook_data_for_route *route_data = NULL; - stream_info *si; - pa_idxset *avail_devices; - uint32_t list_len = 0; - - pa_assert(hook_data); - pa_assert(m); - pa_log_warn("fill_device_info_to_hook_data() for %s", notify_command_type_str[command]); - - switch (command) { - case NOTIFY_COMMAND_SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT: { - select_data = (pa_stream_manager_hook_data_for_select*)hook_data; - si = pa_hashmap_get(m->stream_infos, select_data->stream_role); - select_data->route_type = si->route_type; - avail_devices = (type==STREAM_SINK_INPUT)?si->idx_avail_out_devices:si->idx_avail_in_devices; - list_len = pa_idxset_size(avail_devices); - device_none = pa_idxset_get_by_data(avail_devices, "none", NULL); - if (list_len == 0 || device_none) { - pa_log_warn("there is no available device, stream_type(%d)", type); - break; - } - select_data->idx_avail_devices = avail_devices; - if (si->route_type == STREAM_ROUTE_TYPE_MANUAL) { - p_idx = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_PARENT_ID); - if (p_idx && !pa_atou(p_idx, &parent_idx)) { - /* find parent idx, it's device info. and it's stream idxs */ - sp = pa_hashmap_get(m->stream_parents, (const void*)parent_idx); - if (sp) - select_data->idx_manual_devices = (type==STREAM_SINK_INPUT)?(sp->idx_route_out_devices):(sp->idx_route_in_devices); - else - pa_log_warn("Failed to get the stream parent of idx(%u)", idx); - } - } - break; - } - case NOTIFY_COMMAND_CHANGE_ROUTE_START_WITH_NEW_DATA: - case NOTIFY_COMMAND_CHANGE_ROUTE_START: - case NOTIFY_COMMAND_CHANGE_ROUTE_END: { - route_data = (pa_stream_manager_hook_data_for_route*)hook_data; - si = pa_hashmap_get(m->stream_infos, route_data->stream_role); - avail_devices = (type==STREAM_SINK_INPUT)?si->idx_avail_out_devices:si->idx_avail_in_devices; - route_data->route_type = si->route_type; - list_len = pa_idxset_size(avail_devices); - device_none = pa_idxset_get_by_data(avail_devices, "none", NULL); - - if (command == NOTIFY_COMMAND_CHANGE_ROUTE_START_WITH_NEW_DATA) - p_idx = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_PARENT_ID); - else if (command == NOTIFY_COMMAND_CHANGE_ROUTE_START || command == NOTIFY_COMMAND_CHANGE_ROUTE_END) - p_idx = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_PARENT_ID); - if (p_idx && !pa_atou(p_idx, &parent_idx)) { - sp = pa_hashmap_get(m->stream_parents, (const void*)parent_idx); - if (!sp) - pa_log_warn("Failed to get the stream parent of idx(%u)", parent_idx); - } else - pa_log_warn("Could not get the parent id of this stream, but keep going..."); - - if (list_len == 0 || device_none) { - pa_log_warn("there is no available device, stream_type(%d)", type); - break; - } - route_data->idx_avail_devices = avail_devices; - if (si->route_type == STREAM_ROUTE_TYPE_MANUAL) { - if (sp) { - route_data->idx_manual_devices = (type==STREAM_SINK_INPUT)?(sp->idx_route_out_devices):(sp->idx_route_in_devices); - route_data->idx_streams = (type==STREAM_SINK_INPUT)?(sp->idx_sink_inputs):(sp->idx_source_outputs); - } else - pa_log_warn("Failed to get the stream parent of idx(%u)", parent_idx); - } - break; - } - default: - break; - } - return; -} - -static void do_notify(pa_stream_manager *m, notify_command_type_t command, stream_type_t type, void *user_data) { - pa_stream_manager_hook_data_for_select hook_call_select_data; - pa_stream_manager_hook_data_for_route hook_call_route_data; - pa_stream_manager_hook_data_for_option hook_call_option_data; - hal_stream_connection_info stream_conn_info; - const char *role = NULL; - void *s = NULL; - - pa_assert(m); - pa_log_debug("do_notify(%s): type(%d), user_data(%p)", notify_command_type_str[command], type, user_data); - - switch (command) { - case NOTIFY_COMMAND_SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT: { - pa_assert(user_data); - memset(&hook_call_select_data, 0, sizeof(pa_stream_manager_hook_data_for_select)); - s = user_data; - if (s) { - hook_call_select_data.stream_type = type; - hook_call_select_data.stream_role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type), PA_PROP_MEDIA_ROLE); - fill_device_info_to_hook_data(&hook_call_select_data, command, type, s, m); - hook_call_select_data.sample_spec = GET_STREAM_NEW_SAMPLE_SPEC(s, type); - if (type == STREAM_SINK_INPUT) - hook_call_select_data.proper_sink = &(((pa_sink_input_new_data*)s)->sink); - else if (type == STREAM_SOURCE_OUTPUT) - hook_call_select_data.proper_source = &(((pa_source_output_new_data*)s)->source); - pa_hook_fire(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_SELECT_INIT_SINK_OR_SOURCE), &hook_call_select_data); - } - break; - } - case NOTIFY_COMMAND_CHANGE_ROUTE_START_WITH_NEW_DATA: - case NOTIFY_COMMAND_CHANGE_ROUTE_START: { - pa_assert(user_data); - memset(&hook_call_route_data, 0, sizeof(pa_stream_manager_hook_data_for_route)); - s = user_data; - if (s) { - if (command == NOTIFY_COMMAND_CHANGE_ROUTE_START_WITH_NEW_DATA) { - hook_call_route_data.origins_from_new_data = TRUE; - role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(s, type), PA_PROP_MEDIA_ROLE); - hook_call_route_data.sample_spec = GET_STREAM_NEW_SAMPLE_SPEC(s, type); - if (type == STREAM_SINK_INPUT) { - hook_call_route_data.proper_sink = &(((pa_sink_input_new_data*)s)->sink); - } else if (type == STREAM_SOURCE_OUTPUT) { - hook_call_route_data.proper_source = &(((pa_source_output_new_data*)s)->source); - } - } else { - role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE); - hook_call_route_data.sample_spec = GET_STREAM_SAMPLE_SPEC(s, type); - if (type == STREAM_SINK_INPUT) { - if (((pa_sink_input*)s)->sink) - hook_call_route_data.idx_streams = ((pa_sink_input*)s)->sink->inputs; - } else if (type == STREAM_SOURCE_OUTPUT) { - if (((pa_source_output*)s)->source) - hook_call_route_data.idx_streams = ((pa_source_output*)s)->source->outputs; - } - } - hook_call_route_data.stream_type = type; - hook_call_route_data.stream_role = role; - fill_device_info_to_hook_data(&hook_call_route_data, command, type, s, m); - if (hook_call_route_data.route_type == STREAM_ROUTE_TYPE_MANUAL) { - if (hook_call_route_data.idx_manual_devices && !pa_idxset_size(hook_call_route_data.idx_manual_devices)) { - pa_log_info("no manual device for this type(%d), need to unset route", type); - hook_call_route_data.stream_role = "reset"; - } - } - pa_hook_fire(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_CHANGE_ROUTE), &hook_call_route_data); - } - break; - } - case NOTIFY_COMMAND_CHANGE_ROUTE_END: { - memset(&hook_call_route_data, 0, sizeof(pa_stream_manager_hook_data_for_route)); - s = (type==STREAM_SINK_INPUT)?(void*)(m->cur_highest_priority.sink_input):(void*)(m->cur_highest_priority.source_output); - if (s) { - role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE); - hook_call_route_data.stream_type = type; - hook_call_route_data.stream_role = role; - hook_call_route_data.sample_spec = GET_STREAM_SAMPLE_SPEC(s, type); - hook_call_route_data.idx_streams = (type==STREAM_SINK_INPUT)?((pa_sink_input*)s)->sink->inputs:((pa_source_output*)s)->source->outputs; - fill_device_info_to_hook_data(&hook_call_route_data, command, type, s, m); - } else { - pa_log_info("no stream for this type(%d), need to unset route", type); - hook_call_route_data.stream_type = type; - hook_call_route_data.stream_role = "reset"; - } - pa_hook_fire(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_CHANGE_ROUTE), &hook_call_route_data); - break; - } - case NOTIFY_COMMAND_UPDATE_ROUTE_OPTION: { - pa_assert(user_data); - memset(&hook_call_option_data, 0, sizeof(pa_stream_manager_hook_data_for_option)); - s = (type==STREAM_SINK_INPUT)?(void*)(m->cur_highest_priority.sink_input):(void*)(m->cur_highest_priority.source_output); - if (s) { - role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE); - hook_call_option_data.stream_role = role; - hook_call_option_data.name = ((stream_route_option*)user_data)->name; - hook_call_option_data.value = ((stream_route_option*)user_data)->value; - pa_hook_fire(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_UPDATE_ROUTE_OPTION), &hook_call_option_data); - } - break; - } - case NOTIFY_COMMAND_INFORM_STREAM_CONNECTED: - case NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED: { - pa_assert(user_data); - memset(&stream_conn_info, 0, sizeof(hal_stream_connection_info)); - s = user_data; - if (s) { - stream_conn_info.role = pa_proplist_gets(GET_STREAM_PROPLIST(s, type), PA_PROP_MEDIA_ROLE); - stream_conn_info.direction = (type==STREAM_SINK_INPUT)?DIRECTION_OUT:DIRECTION_IN; - stream_conn_info.idx = (type==STREAM_SINK_INPUT)?((pa_sink_input*)s)->index:((pa_source_output*)s)->index; - stream_conn_info.is_connected = (command == NOTIFY_COMMAND_INFORM_STREAM_CONNECTED)?TRUE:FALSE; - pa_hal_manager_update_stream_connection_info(m->hal, &stream_conn_info); - } - break; - } - } - return; -} - -static process_stream_result_t process_stream(stream_type_t type, void *stream, process_command_type_t command, pa_stream_manager *m) { - process_stream_result_t result = PROCESS_STREAM_RESULT_OK; - const char *role = NULL; - pa_bool_t ret = TRUE; - pa_bool_t need_update = FALSE; - int32_t volume_ret = 0; - volume_info *v = NULL; - const char *si_volume_type_str = NULL; - const int32_t *prior_priority = NULL; - size_t size = 0; - pa_format_info *req_format = NULL; - char *format_str = NULL; - const char *rate_str = NULL; - const char *ch_str = NULL; - - pa_log_info("START process_stream(%s): stream_type(%d), stream(%p), m(%p)", process_command_type_str[command], type, stream, m); - pa_assert(stream); - pa_assert(m); - - if (check_name_to_skip(m, command, type, stream)) { - result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; - } - - if (command == PROCESS_COMMAND_PREPARE) { - if (type == STREAM_SINK_INPUT) { - /* Parse request formats for samplerate, channel, format infomation */ - if (((pa_sink_input_new_data*)stream)->req_formats) { - req_format = pa_idxset_first(((pa_sink_input_new_data*)stream)->req_formats, NULL); - if (req_format && req_format->plist) { - /* set sample_spec */ - rate_str = pa_proplist_gets(req_format->plist, PA_PROP_FORMAT_RATE); - ch_str = pa_proplist_gets(req_format->plist, PA_PROP_FORMAT_CHANNELS); - if (pa_format_info_get_prop_string(req_format, PA_PROP_FORMAT_SAMPLE_FORMAT, &format_str)==0) - ((pa_sink_input_new_data*)stream)->sample_spec.format = pa_parse_sample_format((const char*)format_str); - pa_log_info("req rate(%s), req ch(%s), req format(%s)", rate_str, ch_str, format_str); - if (ch_str) - ((pa_sink_input_new_data*)stream)->sample_spec.channels = atoi (ch_str); - if (rate_str) - ((pa_sink_input_new_data*)stream)->sample_spec.rate = atoi (rate_str); - /* set channel map if it is not set by client */ - if (!((pa_sink_input_new_data*)stream)->channel_map_is_set) { - pa_channel_map_init_auto(&(((pa_sink_input_new_data*)stream)->channel_map), ((pa_sink_input_new_data*)stream)->sample_spec.channels, PA_CHANNEL_MAP_ALSA); - pa_log_info("set default channel_map: channels(%u)",((pa_sink_input_new_data*)stream)->channel_map.channels); - ((pa_sink_input_new_data*)stream)->channel_map_is_set = TRUE; - } - } - } else { - pa_log_debug("no request formats available"); - } - } - role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - if (!role) { - /* set default value for role and priority */ - role = DEFAULT_ROLE; - pa_proplist_sets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE, role); - pa_log_warn("role is null, set default to [%s]", role); - } else { - /* skip roles */ - if (check_role_to_skip(m, role)) { - result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; - } - } - /* update the priority of this stream */ - ret = update_priority_of_stream(m, command, type, stream, role); - if (ret == FALSE) { - pa_log_error("could not update the priority of '%s' role.", role); - result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; - } - /* update the volume type of this stream */ - ret = update_volume_type_of_stream(m, type, stream, role); - if (ret == FALSE) { - pa_log_error("could not update the volume type of '%s' role.", role); - result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; - } - /* update the routing type of this stream */ - ret = update_routing_type_of_stream(m, stream, type, role); - if (ret == FALSE) { - pa_log_error("could not update the route type of '%s' role.", role); - result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; - } - - /* notify to select sink or source */ - do_notify(m, NOTIFY_COMMAND_SELECT_PROPER_SINK_OR_SOURCE_FOR_INIT, type, stream); - - } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA || - command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED) { - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA) - role = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - else - role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - - /* skip roles */ - if (check_role_to_skip(m, role)) { - result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; - } - - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED ) { - /* update the priority of this stream */ - ret = update_priority_of_stream(m, command, type, stream, role); - if (ret == FALSE) { - pa_log_error("could not update the priority of '%s' role.", role); - result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; - } - } - - /* update the focus status */ - ret = update_focus_status_of_stream(m, command, stream, type); - if (ret == FALSE) - pa_log_warn("could not update focus status"); - - /* update the highest priority */ - ret = update_the_highest_priority_stream(m, command, stream, type, role, &need_update); - if (ret == FALSE) { - pa_log_error("could not update the highest priority stream"); - result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; - } - - /* need to skip if this stream does not belong to internal device */ - /* if needed, notify to update */ - if (need_update) { - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA) { - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START_WITH_NEW_DATA, type, stream); - if (type==STREAM_SINK_INPUT) - m->cur_highest_priority.need_to_update_si = TRUE; - else - m->cur_highest_priority.need_to_update_so = TRUE; - } else { - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, type, stream); - if (type==STREAM_SINK_INPUT) - m->cur_highest_priority.sink_input = stream; - else - m->cur_highest_priority.source_output = stream; - } - } - if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED) - do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_CONNECTED, type, stream); - - } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED) { - role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - if (role) { - /* skip roles */ - if (check_role_to_skip(m, role)) { - result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; - } - - /* check if it has already been processed (unlink or state_changed_cb) */ - if (pa_proplist_get(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY, (const void**)&prior_priority, &size)) { - pa_log_debug("it has already been processed for PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, skip it.."); - result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; - } - - pa_proplist_unset(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE_PRIORITY); - ret = update_the_highest_priority_stream(m, command, stream, type, role, &need_update); - if (ret == FALSE) { - pa_log_error("could not update the highest priority stream"); - result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; - } - - do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_DISCONNECTED, type, stream); - - /* need to skip if this stream does not belong to internal device */ - /* if needed, notify to update */ - if (need_update) - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_END, type, NULL); - - } else { - pa_log_error("role is null, skip it"); - } - - } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED) { - role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - if (role) { - /* skip roles */ - if (check_role_to_skip(m, role)) { - result = PROCESS_STREAM_RESULT_SKIP; - goto FAILURE; - } - - ret = update_the_highest_priority_stream(m, command, stream, type, role, &need_update); - if (ret == FALSE) { - pa_log_error("could not update the highest priority stream"); - result = PROCESS_STREAM_RESULT_STOP; - goto FAILURE; - } - - /* need to skip if this stream does not belong to internal device */ - /* if needed, notify to update */ - if (need_update) - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_END, type, NULL); - - } else { - pa_log_error("role is null, skip it"); - } - - } else if (command == PROCESS_COMMAND_UPDATE_VOLUME) { - if ((si_volume_type_str = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) { - v = pa_hashmap_get(m->volume_infos, si_volume_type_str); - if (v && v->values[(type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].idx_volume_values) { - /* Update volume-level */ - volume_ret = set_volume_level_with_new_data(m, type, stream, v->values[(type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].current_level); - if (volume_ret) - pa_log_error("failed to set_volume_level_by_idx(), stream_type(%d), level(%u), ret(0x%x)", - STREAM_SINK_INPUT, v->values[(type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].current_level, volume_ret); - /* Update volume-mute */ - volume_ret = set_volume_mute_with_new_data(m, type, stream, v->values[(type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].is_muted); - if (volume_ret) - pa_log_error("failed to set_volume_mute_by_idx(), stream_type(%d), mute(%d), ret(0x%x)", - STREAM_SINK_INPUT, v->values[(type==STREAM_SINK_INPUT)?STREAM_DIRECTION_OUT:STREAM_DIRECTION_IN].is_muted, volume_ret); - } - } - - } else if (command == PROCESS_COMMAND_ADD_PARENT_ID || command == PROCESS_COMMAND_REMOVE_PARENT_ID) { - if (command == PROCESS_COMMAND_ADD_PARENT_ID) { - if (type == STREAM_SINK_INPUT && m->cur_highest_priority.need_to_update_si) { - m->cur_highest_priority.sink_input = stream; - m->cur_highest_priority.need_to_update_si = FALSE; - } - if (type == STREAM_SOURCE_OUTPUT && m->cur_highest_priority.need_to_update_so) { - m->cur_highest_priority.source_output = stream; - m->cur_highest_priority.need_to_update_so = FALSE; - } - if (command == PROCESS_COMMAND_ADD_PARENT_ID) - do_notify(m, NOTIFY_COMMAND_INFORM_STREAM_CONNECTED, type, stream); - } - /* update parent stream info. */ - ret = update_stream_parent_info(m, command, type, stream); - if (ret == FALSE) { - pa_log_warn("could not update the parent information of this stream"); - //return PROCESS_STREAM_RESULT_STOP; - } - } - -FAILURE: - pa_log_info("END process_stream(%s): result(%d)", process_command_type_str[command], result); - return result; -} - -static void update_buffer_attribute(stream_type_t stream_type, void *new_data, pa_stream_manager *m) { - int32_t maxlength = -1; - int32_t tlength = -1; - int32_t prebuf = -1; - int32_t minreq = -1; - int32_t fragsize = -1; - const char* audio_latency = NULL; - - pa_assert(m); - pa_assert(new_data); - - if (m->hal == NULL) - return; - - audio_latency = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(new_data, stream_type), PA_PROP_MEDIA_TIZEN_AUDIO_LATENCY); - pa_log_info("audio_latency : %s", audio_latency); - if (audio_latency == NULL) - return; - - if (!pa_hal_manager_get_buffer_attribute(m->hal, (io_direction_t)!stream_type, audio_latency, new_data, (uint32_t*)&maxlength, (uint32_t*)&tlength, (uint32_t*)&prebuf, (uint32_t*)&minreq, (uint32_t*)&fragsize)) { - pa_log_info(" - maxlength:%d, tlength:%d, prebuf:%d, minreq:%d, fragsize:%d", maxlength, tlength, prebuf, minreq, fragsize); - pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "maxlength", "%d", maxlength); - pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "tlength", "%d", tlength); - pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "prebuf", "%d", prebuf); - pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "minreq", "%d", minreq); - pa_proplist_setf(GET_STREAM_NEW_PROPLIST(new_data, stream_type), "fragsize", "%d", fragsize); - } - - return; -} - -static pa_hook_result_t sink_input_new_cb(pa_core *core, pa_sink_input_new_data *new_data, pa_stream_manager *m) { - pa_core_assert_ref(core); - - pa_log_info("start sink_input_new_cb"); - - process_stream(STREAM_SINK_INPUT, new_data, PROCESS_COMMAND_PREPARE, m); - /* Update buffer attributes from HAL */ - update_buffer_attribute(STREAM_SINK_INPUT, new_data, m); - process_stream(STREAM_SINK_INPUT, new_data, PROCESS_COMMAND_UPDATE_VOLUME, m); - process_stream(STREAM_SINK_INPUT, new_data, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA, m); - - return PA_HOOK_OK; -} - -static pa_hook_result_t sink_input_put_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) { - pa_core_assert_ref(core); - pa_sink_input_assert_ref(i); - - pa_log_info("start sink_input_put_cb, i(%p, index:%u)", i, i->index); - - process_stream(STREAM_SINK_INPUT, i, PROCESS_COMMAND_ADD_PARENT_ID, m); - - return PA_HOOK_OK; -} - -static pa_hook_result_t sink_input_unlink_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) { - pa_core_assert_ref(core); - pa_sink_input_assert_ref(i); - - pa_log_info("start sink_input_unlink_cb, i(%p, index:%u)", i, i->index); - process_stream(STREAM_SINK_INPUT, i, PROCESS_COMMAND_REMOVE_PARENT_ID, m); - process_stream(STREAM_SINK_INPUT, i, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, m); - - return PA_HOOK_OK; -} - -static pa_hook_result_t sink_input_state_changed_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) { - pa_sink_input_state_t state; - - pa_assert(i); - pa_assert(m); - - state = pa_sink_input_get_state(i); - pa_log_info("start sink_input_state_changed_cb(), sink-input(%p), state(%d)", i, state); - - switch(state) { - case PA_SINK_INPUT_CORKED: { - process_stream(STREAM_SINK_INPUT, i, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, m); - break; - } - case PA_SINK_INPUT_DRAINED: - case PA_SINK_INPUT_RUNNING: { - process_stream(STREAM_SINK_INPUT, i, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, m); - break; - } - default: - break; - } - - return PA_HOOK_OK; -} - -static pa_hook_result_t sink_input_move_start_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) { - pa_core_assert_ref(core); - pa_sink_input_assert_ref(i); - - /* There's no point in doing anything if the core is shut down anyway */ - if (core->state == PA_CORE_SHUTDOWN) - return PA_HOOK_OK; - - pa_log_debug ("sink_input_move_start_cb, i(%p, index:%u)", i, i->index); - - set_volume_mute_by_idx(m, STREAM_SINK_INPUT, i->index, TRUE); - - return PA_HOOK_OK; -} - -static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) { - pa_core_assert_ref(core); - pa_sink_input_assert_ref(i); - - /* There's no point in doing anything if the core is shut down anyway */ - if (core->state == PA_CORE_SHUTDOWN) - return PA_HOOK_OK; - - pa_log_debug ("sink_input_move_finish_cb, i(%p, index:%u)", i, i->index); - - set_volume_mute_by_idx(m, STREAM_SINK_INPUT, i->index, FALSE); - - return PA_HOOK_OK; -} - -static pa_hook_result_t source_output_new_cb(pa_core *core, pa_source_output_new_data *new_data, pa_stream_manager *m) { - pa_core_assert_ref(core); - - pa_log_info("start source_output_new_new_cb"); - - process_stream(STREAM_SOURCE_OUTPUT, new_data, PROCESS_COMMAND_PREPARE, m); - /* Update buffer attributes from HAL */ - update_buffer_attribute(STREAM_SOURCE_OUTPUT, new_data, m); - process_stream(STREAM_SOURCE_OUTPUT, new_data, PROCESS_COMMAND_UPDATE_VOLUME, m); - process_stream(STREAM_SOURCE_OUTPUT, new_data, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED_WITH_NEW_DATA, m); - - return PA_HOOK_OK; -} - -static pa_hook_result_t source_output_put_cb(pa_core *core, pa_source_output *o, pa_stream_manager *m) { - pa_core_assert_ref(core); - pa_source_output_assert_ref(o); - - pa_log_info("start source_output_put_cb, o(%p, index:%u)", o, o->index); - - process_stream(STREAM_SOURCE_OUTPUT, o, PROCESS_COMMAND_ADD_PARENT_ID, m); - - return PA_HOOK_OK; -} - -static pa_hook_result_t source_output_unlink_cb(pa_core *core, pa_source_output *o, pa_stream_manager *m) { - pa_core_assert_ref(core); - pa_source_output_assert_ref(o); - - pa_log_info("start source_output_unlink_cb, o(%p, index:%u)", o, o->index); - - process_stream(STREAM_SOURCE_OUTPUT, o, PROCESS_COMMAND_REMOVE_PARENT_ID, m); - process_stream(STREAM_SOURCE_OUTPUT, o, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, m); - - return PA_HOOK_OK; -} - -static pa_hook_result_t source_output_state_changed_cb(pa_core *core, pa_source_output *o, pa_stream_manager *m) { - pa_source_output_state_t state; - - pa_assert(o); - pa_assert(m); - - state = pa_source_output_get_state(o); - pa_log_debug("start source_output_state_changed_cb(), source-output(%p), state(%d)", o, state); - - switch(state) { - case PA_SOURCE_OUTPUT_CORKED: { - process_stream(STREAM_SOURCE_OUTPUT, o, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, m); - break; - } - case PA_SOURCE_OUTPUT_RUNNING: { - process_stream(STREAM_SOURCE_OUTPUT, o, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, m); - break; - } - default: - break; - } - - return PA_HOOK_OK; -} - -/* Reorganize routing when a device has been connected or disconnected */ -static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *conn, pa_stream_manager *m) { - const char *route_type_str = NULL; - stream_route_type_t route_type; - dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT; - - device_direction = pa_device_manager_get_device_direction(conn->device); - pa_log_info("device_connection_changed_hook_cb is called. conn(%p), is_connected(%d), device(%p), direction(0x%x)", - conn, conn->is_connected, conn->device, device_direction); - - /* If the route type of the stream is not manual, notify again */ - if (m->cur_highest_priority.source_output && (device_direction & DM_DEVICE_DIRECTION_IN)) { - route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(m->cur_highest_priority.source_output, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROLE_ROUTE_TYPE); - if(!pa_atoi(route_type_str, (int32_t*)&route_type)) - if (route_type != STREAM_ROUTE_TYPE_MANUAL) - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, m->cur_highest_priority.source_output); - } if (m->cur_highest_priority.sink_input && (device_direction & DM_DEVICE_DIRECTION_OUT)) { - route_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(m->cur_highest_priority.sink_input, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROLE_ROUTE_TYPE); - if(!pa_atoi(route_type_str, (int32_t*)&route_type)) - if (route_type != STREAM_ROUTE_TYPE_MANUAL) - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, m->cur_highest_priority.sink_input); - } - - return PA_HOOK_OK; -} - -/* Reorganize routing when device information has been changed */ -static pa_hook_result_t device_information_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_info_changed *info, pa_stream_manager *m) { - pa_log_info("device_information_changed_hook_cb is called. info(%p), changed_info(%d), device(%p)", - info, info->changed_info, info->device); - - return PA_HOOK_OK; -} - -static void subscribe_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, pa_stream_manager *m) { - pa_client *client = NULL; - stream_parent *sp = NULL; - const char *name = NULL; - uint32_t *device_id = NULL; - uint32_t _idx = 0; - pa_core_assert_ref(core); - pa_assert(m); - pa_log_info("subscribe_cb() is called, t(%x), idx(%u)", t, idx); - - if (t == (PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE)) { - client = pa_idxset_get_by_index(core->clients, idx); - if (client == NULL) { - pa_log_error(" - could not find any client that has idx(%u)", idx); - return; - } - name = pa_proplist_gets(client->proplist, PA_PROP_APPLICATION_NAME); - if (strncmp (name, STREAM_MANAGER_CLIENT_NAME, strlen(STREAM_MANAGER_CLIENT_NAME))) { - pa_log_warn(" - this is not a client(%s) that we should take care of, skip it", name); - return; - } - /* add a stream parent */ - sp = pa_xmalloc0(sizeof(stream_parent)); - sp->idx_sink_inputs = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - sp->idx_source_outputs = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - sp->idx_route_in_devices = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - sp->idx_route_out_devices = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - pa_hashmap_put(m->stream_parents, (void*)idx, sp); - pa_log_debug(" - add sp(%p), idx(%u)", sp, idx); - } else if (t == (PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE)) { - /* remove the stream parent */ - sp = pa_hashmap_get(m->stream_parents, (const void*)idx); - if (sp) { - pa_log_debug(" - remove sp(%p), idx(%u)", sp, idx); - pa_hashmap_remove(m->stream_parents, (const void*)idx); - if (sp->idx_route_in_devices) - PA_IDXSET_FOREACH(device_id, sp->idx_route_in_devices, _idx) - pa_xfree(device_id); - if (sp->idx_route_out_devices) - PA_IDXSET_FOREACH(device_id, sp->idx_route_out_devices, _idx) - pa_xfree(device_id); - pa_idxset_free(sp->idx_sink_inputs, NULL); - pa_idxset_free(sp->idx_source_outputs, NULL); - pa_idxset_free(sp->idx_route_in_devices, NULL); - pa_idxset_free(sp->idx_route_out_devices, NULL); - pa_xfree(sp); - } else { - pa_log_error(" - could not find any stream_parent that has idx(%u)", idx); - } - } -} - -static int init_ipc (pa_stream_manager *m) { -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - pa_assert(m); - pa_log_info("Initialization for IPC"); - m->dbus_protocol = pa_dbus_protocol_get(m->core); - pa_assert_se(pa_dbus_protocol_add_interface(m->dbus_protocol, STREAM_MANAGER_OBJECT_PATH, &stream_manager_interface_info, m) >= 0); - pa_assert_se(pa_dbus_protocol_register_extension(m->dbus_protocol, STREAM_MANAGER_INTERFACE) >= 0); -#else - DBusError err; - pa_dbus_connection *conn = NULL; - static const DBusObjectPathVTable vtable = { - .message_function = method_handler_for_vt, - }; - - pa_assert(m); - pa_log_info("Initialization for IPC"); - - dbus_error_init(&err); - - if (!(conn = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &err)) || dbus_error_is_set(&err)) { - if (conn) { - pa_dbus_connection_unref(conn); - } - pa_log_error("Unable to contact D-Bus system bus: %s: %s", err.name, err.message); - goto fail; - } else { - pa_log_notice("Got dbus connection"); - } - m->dbus_conn = conn; - pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(conn), STREAM_MANAGER_OBJECT_PATH, &vtable, m)); -#endif -#else - pa_log_error("DBUS is not supported\n"); - goto fail; -#endif - - return 0; -fail: - pa_log_error("Failed to initialize stream manager ipc"); - return -1; -} - -static void deinit_ipc (pa_stream_manager *m) { - pa_assert(m); - -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - if (m->dbus_protocol) { - pa_assert_se(pa_dbus_protocol_unregister_extension(m->dbus_protocol, STREAM_MANAGER_INTERFACE) >= 0); - pa_assert_se(pa_dbus_protocol_remove_interface(m->dbus_protocol, STREAM_MANAGER_OBJECT_PATH, stream_manager_interface_info.name) >= 0); - pa_dbus_protocol_unref(m->dbus_protocol); - m->dbus_protocol = NULL; - } -#else - if (m->dbus_conn) { - if(!dbus_connection_unregister_object_path(pa_dbus_connection_get(m->dbus_conn), STREAM_MANAGER_OBJECT_PATH)) - pa_log_error("Failed to unregister object path"); - m->dbus_conn = NULL; - } -#endif -#endif - return; -} - -pa_stream_manager* pa_stream_manager_init(pa_core *c) { - pa_stream_manager *m; - - pa_assert(c); - - m = pa_xnew0(pa_stream_manager, 1); - m->core = c; - - m->hal = pa_hal_manager_get(c, NULL); - -#ifdef HAVE_DBUS -#ifdef USE_DBUS_PROTOCOL - m->dbus_protocol = NULL; -#else - m->dbus_conn = NULL; -#endif -#endif - if (init_ipc(m)) - goto fail; - - if (init_stream_map(m)) - goto fail; - - if (init_volumes(m)) - goto fail; - - m->stream_parents = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - - m->sink_input_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_new_cb, m); - m->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_put_cb, m); - m->sink_input_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_unlink_cb, m); - m->sink_input_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_state_changed_cb, m); - m->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_move_start_cb, m); - m->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_move_finish_cb, m); - m->source_output_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_new_cb, m); - m->source_output_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_put_cb, m); - m->source_output_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_unlink_cb, m); - m->source_output_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_STATE_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_state_changed_cb, m); - - - m->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_CLIENT | PA_SUBSCRIPTION_MASK_SAMPLE_CACHE, (pa_subscription_cb_t)subscribe_cb, m); - - m->comm.comm = pa_communicator_get(c); - m->comm.comm_hook_device_connection_changed_slot = pa_hook_connect(pa_communicator_hook(m->comm.comm,PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), - PA_HOOK_EARLY + 10, (pa_hook_cb_t) device_connection_changed_hook_cb, m); - m->comm.comm_hook_device_information_changed_slot = pa_hook_connect(pa_communicator_hook(m->comm.comm,PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), - PA_HOOK_EARLY, (pa_hook_cb_t) device_information_changed_hook_cb, m); - - return m; - -fail: - pa_log_error("Failed to initialize stream-manager"); - deinit_volumes(m); - deinit_stream_map(m); - deinit_ipc(m); - if (m->hal) - pa_hal_manager_unref(m->hal); - pa_xfree(m); - return 0; -} - -void pa_stream_manager_done(pa_stream_manager *m) { - pa_assert(m); - - if (m->comm.comm) { - if (m->comm.comm_hook_device_connection_changed_slot) - pa_hook_slot_free(m->comm.comm_hook_device_connection_changed_slot); - if (m->comm.comm_hook_device_information_changed_slot) - pa_hook_slot_free(m->comm.comm_hook_device_information_changed_slot); - pa_communicator_unref(m->comm.comm); - } - - if (m->subscription) - pa_subscription_free(m->subscription); - - if (m->sink_input_new_slot) - pa_hook_slot_free(m->sink_input_new_slot); - if (m->sink_input_put_slot) - pa_hook_slot_free(m->sink_input_put_slot); - if (m->sink_input_unlink_slot) - pa_hook_slot_free(m->sink_input_unlink_slot); - if (m->sink_input_state_changed_slot) - pa_hook_slot_free(m->sink_input_state_changed_slot); - if (m->sink_input_move_start_slot) - pa_hook_slot_free(m->sink_input_move_start_slot); - if (m->sink_input_move_finish_slot) - pa_hook_slot_free(m->sink_input_move_finish_slot); - if (m->source_output_new_slot) - pa_hook_slot_free(m->source_output_new_slot); - if (m->source_output_put_slot) - pa_hook_slot_free(m->source_output_put_slot); - if (m->source_output_unlink_slot) - pa_hook_slot_free(m->source_output_unlink_slot); - if (m->source_output_state_changed_slot) - pa_hook_slot_free(m->source_output_state_changed_slot); - - if (m->stream_parents) - pa_hashmap_free(m->stream_parents); - - deinit_volumes(m); - deinit_stream_map(m); - deinit_ipc(m); - - if (m->hal) - pa_hal_manager_unref(m->hal); - - pa_xfree(m); -} diff --git a/src/modules/tizen/stream-manager.h b/src/modules/tizen/stream-manager.h deleted file mode 100644 index 02dc5db..0000000 --- a/src/modules/tizen/stream-manager.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef foostreammanagerfoo -#define foostreammanagerfoo -#include - -typedef struct _stream_manager pa_stream_manager; - -typedef enum _stream_type { - STREAM_SINK_INPUT, - STREAM_SOURCE_OUTPUT, -} stream_type_t; - -typedef enum stream_route_type { - STREAM_ROUTE_TYPE_AUTO, /* the policy of decision device(s) is automatic and it's routing path is particular to one device */ - STREAM_ROUTE_TYPE_AUTO_ALL, /* the policy of decision device(s) is automatic and it's routing path can be several devices */ - STREAM_ROUTE_TYPE_MANUAL, /* the policy of decision device(s) is manual */ -} stream_route_type_t; - -typedef struct _hook_call_data_for_select { - const char *stream_role; - stream_type_t stream_type; - stream_route_type_t route_type; - pa_sink **proper_sink; - pa_source **proper_source; - pa_sample_spec sample_spec; - pa_idxset *idx_avail_devices; - pa_idxset *idx_manual_devices; -} pa_stream_manager_hook_data_for_select; - -typedef struct _hook_call_data_for_route { - const char *stream_role; - stream_type_t stream_type; - stream_route_type_t route_type; - pa_sink **proper_sink; - pa_source **proper_source; - pa_sample_spec sample_spec; - pa_idxset *idx_avail_devices; - pa_idxset *idx_manual_devices; - pa_idxset *idx_streams; - pa_bool_t origins_from_new_data; -} pa_stream_manager_hook_data_for_route; - -typedef struct _hook_call_data_for_option { - const char *stream_role; - const char *name; - int32_t value; -} pa_stream_manager_hook_data_for_option; - -pa_stream_manager* pa_stream_manager_init(pa_core *c); -void pa_stream_manager_done(pa_stream_manager* m); - -#endif -- 2.7.4