From 9a77d2f81d693d64b63d38be7214626dedf91e11 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 21 Jul 2009 00:04:52 +0300 Subject: Add the forgotten src/modules/dbus directory to git. --- src/modules/dbus/iface-core.c | 1968 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1968 insertions(+) create mode 100644 src/modules/dbus/iface-core.c (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c new file mode 100644 index 00000000..31f12603 --- /dev/null +++ b/src/modules/dbus/iface-core.c @@ -0,0 +1,1968 @@ +/*** + This file is part of PulseAudio. + + Copyright 2009 Tanu Kaskinen + + 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 "iface-card.h" +#include "iface-client.h" +#include "iface-device.h" +#include "iface-module.h" +#include "iface-sample.h" +#include "iface-stream.h" + +#include "iface-core.h" + +#define OBJECT_PATH "/org/pulseaudio/core1" +#define INTERFACE_CORE "org.PulseAudio.Core1" + +#define INTERFACE_REVISION 0 + + + +static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_version(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_is_local(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_username(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_hostname(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_modules(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_clients(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_my_client(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_extensions(DBusConnection *conn, DBusMessage *msg, void *userdata); + +static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata); + +static void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata); + +struct pa_dbusiface_core { + pa_core *core; + pa_subscription *subscription; + + pa_dbus_protocol *dbus_protocol; + + pa_hashmap *cards; + pa_hashmap *sinks_by_index; + pa_hashmap *sinks_by_path; + pa_hashmap *sources_by_index; + pa_hashmap *sources_by_path; + pa_hashmap *playback_streams; + pa_hashmap *record_streams; + pa_hashmap *samples; + pa_hashmap *modules; + pa_hashmap *clients; + + pa_sink *fallback_sink; + pa_source *fallback_source; +}; + +enum property_handler_index { + PROPERTY_HANDLER_INTERFACE_REVISION, + PROPERTY_HANDLER_NAME, + PROPERTY_HANDLER_VERSION, + PROPERTY_HANDLER_IS_LOCAL, + PROPERTY_HANDLER_USERNAME, + PROPERTY_HANDLER_HOSTNAME, + PROPERTY_HANDLER_DEFAULT_CHANNELS, + PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT, + PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE, + PROPERTY_HANDLER_CARDS, + PROPERTY_HANDLER_SINKS, + PROPERTY_HANDLER_FALLBACK_SINK, + PROPERTY_HANDLER_SOURCES, + PROPERTY_HANDLER_FALLBACK_SOURCE, + PROPERTY_HANDLER_PLAYBACK_STREAMS, + PROPERTY_HANDLER_RECORD_STREAMS, + PROPERTY_HANDLER_SAMPLES, + PROPERTY_HANDLER_MODULES, + PROPERTY_HANDLER_CLIENTS, + PROPERTY_HANDLER_MY_CLIENT, + PROPERTY_HANDLER_EXTENSIONS, + PROPERTY_HANDLER_MAX +}; + +static pa_dbus_property_handler property_handlers[PROPERTY_HANDLER_MAX] = { + [PROPERTY_HANDLER_INTERFACE_REVISION] = { .property_name = "InterfaceRevision", .type = "u", .get_cb = handle_get_interface_revision, .set_cb = NULL }, + [PROPERTY_HANDLER_NAME] = { .property_name = "Name", .type = "s", .get_cb = handle_get_name, .set_cb = NULL }, + [PROPERTY_HANDLER_VERSION] = { .property_name = "Version", .type = "s", .get_cb = handle_get_version, .set_cb = NULL }, + [PROPERTY_HANDLER_IS_LOCAL] = { .property_name = "IsLocal", .type = "b", .get_cb = handle_get_is_local, .set_cb = NULL }, + [PROPERTY_HANDLER_USERNAME] = { .property_name = "Username", .type = "s", .get_cb = handle_get_username, .set_cb = NULL }, + [PROPERTY_HANDLER_HOSTNAME] = { .property_name = "Hostname", .type = "s", .get_cb = handle_get_hostname, .set_cb = NULL }, + [PROPERTY_HANDLER_DEFAULT_CHANNELS] = { .property_name = "DefaultChannels", .type = "au", .get_cb = handle_get_default_channels, .set_cb = handle_set_default_channels }, + [PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT] = { .property_name = "DefaultSampleFormat", .type = "u", .get_cb = handle_get_default_sample_format, .set_cb = handle_set_default_sample_format }, + [PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE] = { .property_name = "DefaultSampleRate", .type = "u", .get_cb = handle_get_default_sample_rate, .set_cb = handle_set_default_sample_rate }, + [PROPERTY_HANDLER_CARDS] = { .property_name = "Cards", .type = "ao", .get_cb = handle_get_cards, .set_cb = NULL }, + [PROPERTY_HANDLER_SINKS] = { .property_name = "Sinks", .type = "ao", .get_cb = handle_get_sinks, .set_cb = NULL }, + [PROPERTY_HANDLER_FALLBACK_SINK] = { .property_name = "FallbackSink", .type = "o", .get_cb = handle_get_fallback_sink, .set_cb = handle_set_fallback_sink }, + [PROPERTY_HANDLER_SOURCES] = { .property_name = "Sources", .type = "ao", .get_cb = handle_get_sources, .set_cb = NULL }, + [PROPERTY_HANDLER_FALLBACK_SOURCE] = { .property_name = "FallbackSource", .type = "o", .get_cb = handle_get_fallback_source, .set_cb = handle_set_fallback_source }, + [PROPERTY_HANDLER_PLAYBACK_STREAMS] = { .property_name = "PlaybackStreams", .type = "ao", .get_cb = handle_get_playback_streams, .set_cb = NULL }, + [PROPERTY_HANDLER_RECORD_STREAMS] = { .property_name = "RecordStreams", .type = "ao", .get_cb = handle_get_record_streams, .set_cb = NULL }, + [PROPERTY_HANDLER_SAMPLES] = { .property_name = "Samples", .type = "ao", .get_cb = handle_get_samples, .set_cb = NULL }, + [PROPERTY_HANDLER_MODULES] = { .property_name = "Modules", .type = "ao", .get_cb = handle_get_modules, .set_cb = NULL }, + [PROPERTY_HANDLER_CLIENTS] = { .property_name = "Clients", .type = "ao", .get_cb = handle_get_clients, .set_cb = NULL }, + [PROPERTY_HANDLER_MY_CLIENT] = { .property_name = "MyClient", .type = "o", .get_cb = handle_get_my_client, .set_cb = NULL }, + [PROPERTY_HANDLER_EXTENSIONS] = { .property_name = "Extensions", .type = "as", .get_cb = handle_get_extensions, .set_cb = NULL } +}; + +enum method_handler_index { + METHOD_HANDLER_GET_CARD_BY_NAME, + METHOD_HANDLER_GET_SINK_BY_NAME, + METHOD_HANDLER_GET_SOURCE_BY_NAME, + METHOD_HANDLER_GET_SAMPLE_BY_NAME, + METHOD_HANDLER_UPLOAD_SAMPLE, + METHOD_HANDLER_LOAD_MODULE, + METHOD_HANDLER_EXIT, + METHOD_HANDLER_LISTEN_FOR_SIGNAL, + METHOD_HANDLER_STOP_LISTENING_FOR_SIGNAL, + METHOD_HANDLER_MAX +}; + +static pa_dbus_arg_info get_card_by_name_args[] = { { "name", "s", "in" }, { "card", "o", "out" } }; +static pa_dbus_arg_info get_sink_by_name_args[] = { { "name", "s", "in" }, { "sink", "o", "out" } }; +static pa_dbus_arg_info get_source_by_name_args[] = { { "name", "s", "in" }, { "source", "o", "out" } }; +static pa_dbus_arg_info get_sample_by_name_args[] = { { "name", "s", "in" }, { "sample", "o", "out" } }; +static pa_dbus_arg_info upload_sample_args[] = { { "name", "s", "in" }, + { "sample_format", "u", "in" }, + { "sample_rate", "u", "in" }, + { "channels", "au", "in" }, + { "default_volume", "au", "in" }, + { "property_list", "a{say}", "in" }, + { "data", "ay", "in" }, + { "sample", "o", "out" } }; +static pa_dbus_arg_info load_module_args[] = { { "name", "s", "in" }, { "arguments", "a{ss}", "in" }, { "module", "o", "out" } }; +static pa_dbus_arg_info listen_for_signal_args[] = { { "signal", "s", "in" }, { "objects", "ao", "in" } }; +static pa_dbus_arg_info stop_listening_for_signal_args[] = { { "signal", "s", "in" } }; + +static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { + [METHOD_HANDLER_GET_CARD_BY_NAME] = { + .method_name = "GetCardByName", + .arguments = get_card_by_name_args, + .n_arguments = sizeof(get_card_by_name_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_get_card_by_name }, + [METHOD_HANDLER_GET_SINK_BY_NAME] = { + .method_name = "GetSinkByName", + .arguments = get_sink_by_name_args, + .n_arguments = sizeof(get_sink_by_name_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_get_sink_by_name }, + [METHOD_HANDLER_GET_SOURCE_BY_NAME] = { + .method_name = "GetSourceByName", + .arguments = get_source_by_name_args, + .n_arguments = sizeof(get_source_by_name_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_get_source_by_name }, + [METHOD_HANDLER_GET_SAMPLE_BY_NAME] = { + .method_name = "GetSampleByName", + .arguments = get_sample_by_name_args, + .n_arguments = sizeof(get_sample_by_name_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_get_sample_by_name }, + [METHOD_HANDLER_UPLOAD_SAMPLE] = { + .method_name = "UploadSample", + .arguments = upload_sample_args, + .n_arguments = sizeof(upload_sample_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_upload_sample }, + [METHOD_HANDLER_LOAD_MODULE] = { + .method_name = "LoadModule", + .arguments = upload_sample_args, + .n_arguments = sizeof(load_module_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_load_module }, + [METHOD_HANDLER_EXIT] = { + .method_name = "Exit", + .arguments = NULL, + .n_arguments = 0, + .receive_cb = handle_exit }, + [METHOD_HANDLER_LISTEN_FOR_SIGNAL] = { + .method_name = "ListenForSignal", + .arguments = listen_for_signal_args, + .n_arguments = sizeof(listen_for_signal_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_listen_for_signal }, + [METHOD_HANDLER_STOP_LISTENING_FOR_SIGNAL] = { + .method_name = "StopListeningForSignal", + .arguments = stop_listening_for_signal_args, + .n_arguments = sizeof(stop_listening_for_signal_args) / sizeof(pa_dbus_arg_info), + .receive_cb = handle_stop_listening_for_signal } +}; + +enum signal_index { + SIGNAL_NEW_CARD, + SIGNAL_CARD_REMOVED, + SIGNAL_NEW_SINK, + SIGNAL_SINK_REMOVED, + SIGNAL_FALLBACK_SINK_UPDATED, + SIGNAL_NEW_SOURCE, + SIGNAL_SOURCE_REMOVED, + SIGNAL_FALLBACK_SOURCE_UPDATED, + SIGNAL_NEW_PLAYBACK_STREAM, + SIGNAL_PLAYBACK_STREAM_REMOVED, + SIGNAL_NEW_RECORD_STREAM, + SIGNAL_RECORD_STREAM_REMOVED, + SIGNAL_NEW_SAMPLE, + SIGNAL_SAMPLE_REMOVED, + SIGNAL_NEW_MODULE, + SIGNAL_MODULE_REMOVED, + SIGNAL_NEW_CLIENT, + SIGNAL_CLIENT_REMOVED, + SIGNAL_MAX +}; + +static pa_dbus_arg_info new_card_args[] = { { "card", "o", NULL } }; +static pa_dbus_arg_info card_removed_args[] = { { "card", "o", NULL } }; +static pa_dbus_arg_info new_sink_args[] = { { "sink", "o", NULL } }; +static pa_dbus_arg_info sink_removed_args[] = { { "sink", "o", NULL } }; +static pa_dbus_arg_info fallback_sink_updated_args[] = { { "sink", "o", NULL } }; +static pa_dbus_arg_info new_source_args[] = { { "source", "o", NULL } }; +static pa_dbus_arg_info source_removed_args[] = { { "source", "o", NULL } }; +static pa_dbus_arg_info fallback_source_updated_args[] = { { "source", "o", NULL } }; +static pa_dbus_arg_info new_playback_stream_args[] = { { "playback_stream", "o", NULL } }; +static pa_dbus_arg_info playback_stream_removed_args[] = { { "playback_stream", "o", NULL } }; +static pa_dbus_arg_info new_record_stream_args[] = { { "record_stream", "o", NULL } }; +static pa_dbus_arg_info record_stream_removed_args[] = { { "record_stream", "o", NULL } }; +static pa_dbus_arg_info new_sample_args[] = { { "sample", "o", NULL } }; +static pa_dbus_arg_info sample_removed_args[] = { { "sample", "o", NULL } }; +static pa_dbus_arg_info new_module_args[] = { { "module", "o", NULL } }; +static pa_dbus_arg_info module_removed_args[] = { { "module", "o", NULL } }; +static pa_dbus_arg_info new_client_args[] = { { "client", "o", NULL } }; +static pa_dbus_arg_info client_removed_args[] = { { "client", "o", NULL } }; + +static pa_dbus_signal_info signals[SIGNAL_MAX] = { + [SIGNAL_NEW_CARD] = { .name = "NewCard", .arguments = new_card_args, .n_arguments = 1 }, + [SIGNAL_CARD_REMOVED] = { .name = "CardRemoved", .arguments = card_removed_args, .n_arguments = 1 }, + [SIGNAL_NEW_SINK] = { .name = "NewSink", .arguments = new_sink_args, .n_arguments = 1 }, + [SIGNAL_SINK_REMOVED] = { .name = "SinkRemoved", .arguments = sink_removed_args, .n_arguments = 1 }, + [SIGNAL_FALLBACK_SINK_UPDATED] = { .name = "FallbackSinkUpdated", .arguments = fallback_sink_updated_args, .n_arguments = 1 }, + [SIGNAL_NEW_SOURCE] = { .name = "NewSource", .arguments = new_source_args, .n_arguments = 1 }, + [SIGNAL_SOURCE_REMOVED] = { .name = "SourceRemoved", .arguments = source_removed_args, .n_arguments = 1 }, + [SIGNAL_FALLBACK_SOURCE_UPDATED] = { .name = "FallbackSourceUpdated", .arguments = fallback_source_updated_args, .n_arguments = 1 }, + [SIGNAL_NEW_PLAYBACK_STREAM] = { .name = "NewPlaybackStream", .arguments = new_playback_stream_args, .n_arguments = 1 }, + [SIGNAL_PLAYBACK_STREAM_REMOVED] = { .name = "PlaybackStreamRemoved", .arguments = playback_stream_removed_args, .n_arguments = 1 }, + [SIGNAL_NEW_RECORD_STREAM] = { .name = "NewRecordStream", .arguments = new_record_stream_args, .n_arguments = 1 }, + [SIGNAL_RECORD_STREAM_REMOVED] = { .name = "RecordStreamRemoved", .arguments = record_stream_removed_args, .n_arguments = 1 }, + [SIGNAL_NEW_SAMPLE] = { .name = "NewSample", .arguments = new_sample_args, .n_arguments = 1 }, + [SIGNAL_SAMPLE_REMOVED] = { .name = "SampleRemoved", .arguments = sample_removed_args, .n_arguments = 1 }, + [SIGNAL_NEW_MODULE] = { .name = "NewModule", .arguments = new_module_args, .n_arguments = 1 }, + [SIGNAL_MODULE_REMOVED] = { .name = "ModuleRemoved", .arguments = module_removed_args, .n_arguments = 1 }, + [SIGNAL_NEW_CLIENT] = { .name = "NewClient", .arguments = new_client_args, .n_arguments = 1 }, + [SIGNAL_CLIENT_REMOVED] = { .name = "ClientRemoved", .arguments = client_removed_args, .n_arguments = 1 }, +}; + +static pa_dbus_interface_info core_interface_info = { + .name = INTERFACE_CORE, + .method_handlers = method_handlers, + .n_method_handlers = METHOD_HANDLER_MAX, + .property_handlers = property_handlers, + .n_property_handlers = PROPERTY_HANDLER_MAX, + .get_all_properties_cb = handle_get_all, + .signals = signals, + .n_signals = SIGNAL_MAX +}; + +static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata) { + dbus_uint32_t interface_revision = INTERFACE_REVISION; + + pa_assert(conn); + pa_assert(msg); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &interface_revision); +} + +static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { + const char *server_name = PACKAGE_NAME; + + pa_assert(conn); + pa_assert(msg); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &server_name); +} + +static void handle_get_version(DBusConnection *conn, DBusMessage *msg, void *userdata) { + const char *version = PACKAGE_VERSION; + + pa_assert(conn); + pa_assert(msg); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &version); +} + +static dbus_bool_t get_is_local(DBusConnection *conn) { + int conn_fd; + + pa_assert(conn); + + if (!dbus_connection_get_socket(conn, &conn_fd)) + return FALSE; + + return pa_socket_is_local(conn_fd); +} + +static void handle_get_is_local(DBusConnection *conn, DBusMessage *msg, void *userdata) { + dbus_bool_t is_local; + + pa_assert(conn); + pa_assert(msg); + + is_local = get_is_local(conn); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_BOOLEAN, &is_local); +} + +static void handle_get_username(DBusConnection *conn, DBusMessage *msg, void *userdata) { + char *username = NULL; + + pa_assert(conn); + pa_assert(msg); + + username = pa_get_user_name_malloc(); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &username); + + pa_xfree(username); +} + +static void handle_get_hostname(DBusConnection *conn, DBusMessage *msg, void *userdata) { + char *hostname = NULL; + + pa_assert(conn); + pa_assert(msg); + + hostname = pa_get_host_name_malloc(); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_STRING, &hostname); + + pa_xfree(hostname); +} + +/* Caller frees the returned array. */ +static dbus_uint32_t *get_default_channels(pa_dbusiface_core *c, unsigned *n) { + dbus_uint32_t *default_channels = NULL; + unsigned i; + + pa_assert(c); + pa_assert(n); + + *n = c->core->default_channel_map.channels; + default_channels = pa_xnew(dbus_uint32_t, *n); + + for (i = 0; i < *n; ++i) + default_channels[i] = c->core->default_channel_map.map[i]; + + return default_channels; +} + +static void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + dbus_uint32_t *default_channels = NULL; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + default_channels = get_default_channels(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_UINT32, default_channels, n); + + pa_xfree(default_channels); +} + +static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + pa_channel_map new_channel_map; + DBusMessageIter msg_iter; + DBusMessageIter variant_iter; + DBusMessageIter array_iter; + dbus_uint32_t *default_channels; + int n_channels; + unsigned i; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + pa_channel_map_init(&new_channel_map); + + pa_assert_se(dbus_message_iter_init(msg, &msg_iter)); + + /* Skip the interface and property name arguments. */ + if (!dbus_message_iter_next(&msg_iter) || !dbus_message_iter_next(&msg_iter)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments."); + return; + } + + if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_VARIANT) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Message argument isn't a variant."); + return; + } + + dbus_message_iter_recurse(&msg_iter, &variant_iter); + + if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Variant doesn't contain an array."); + return; + } + + dbus_message_iter_recurse(&variant_iter, &array_iter); + + if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_UINT32) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Array type is not uint32."); + return; + } + + dbus_message_iter_get_fixed_array(&array_iter, &default_channels, &n_channels); + + if (n_channels <= 0) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel array."); + return; + } + + new_channel_map.channels = n_channels; + + for (i = 0; i < new_channel_map.channels; ++i) { + if (default_channels[i] >= PA_CHANNEL_POSITION_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position."); + return; + } + + new_channel_map.map[i] = default_channels[i]; + } + + c->core->default_channel_map = new_channel_map; + c->core->default_sample_spec.channels = n_channels; + + pa_dbus_send_empty_reply(conn, msg); +}; + +static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + dbus_uint32_t default_sample_format; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + default_sample_format = c->core->default_sample_spec.format; + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_format); +} + +static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + dbus_uint32_t default_sample_format; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &default_sample_format) < 0) + return; + + if (default_sample_format >= PA_SAMPLE_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); + return; + } + + c->core->default_sample_spec.format = default_sample_format; + + pa_dbus_send_empty_reply(conn, msg); +} + +static void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + dbus_uint32_t default_sample_rate; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + default_sample_rate = c->core->default_sample_spec.rate; + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_rate); +} + +static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + dbus_uint32_t default_sample_rate; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &default_sample_rate) < 0) + return; + + if (default_sample_rate <= 0 || default_sample_rate > PA_RATE_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); + return; + } + + c->core->default_sample_spec.rate = default_sample_rate; + + pa_dbus_send_empty_reply(conn, msg); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_cards(pa_dbusiface_core *c, unsigned *n) { + const char **cards; + unsigned i; + void *state = NULL; + pa_dbusiface_card *card; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->cards); + + if (*n == 0) + return NULL; + + cards = pa_xnew(const char *, *n); + + for (i = 0, card = pa_hashmap_iterate(c->cards, &state, NULL); card; ++i, card = pa_hashmap_iterate(c->cards, &state, NULL)) + cards[i] = pa_dbusiface_card_get_path(card); + + pa_assert(i == *n); + + return cards; +} + +static void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **cards; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + cards = get_cards(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, cards, n); + + pa_xfree(cards); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_sinks(pa_dbusiface_core *c, unsigned *n) { + const char **sinks; + unsigned i; + void *state = NULL; + pa_dbusiface_device *sink; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->sinks_by_index); + + if (*n == 0) + return NULL; + + sinks = pa_xnew(const char *, *n); + + for (i = 0, sink = pa_hashmap_iterate(c->sinks_by_index, &state, NULL); sink; ++i, sink = pa_hashmap_iterate(c->sinks_by_index, &state, NULL)) + sinks[i] = pa_dbusiface_device_get_path(sink); + + pa_assert(i == *n); + + return sinks; +} + +static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **sinks; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + sinks = get_sinks(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sinks, n); + + pa_xfree(sinks); +} + +static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + pa_dbusiface_device *fallback_sink; + const char *object_path; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (!c->fallback_sink) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sinks, and therefore no fallback sink either."); + return; + } + + pa_assert_se((fallback_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index)))); + object_path = pa_dbusiface_device_get_path(fallback_sink); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); +} + +static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + pa_dbusiface_device *fallback_sink; + const char *object_path; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (!c->fallback_sink) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sinks, and therefore no fallback sink either."); + return; + } + + if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path) < 0) + return; + + if (!(fallback_sink = pa_hashmap_get(c->sinks_by_path, object_path))) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sink."); + return; + } + + pa_namereg_set_default_sink(c->core, pa_dbusiface_device_get_sink(fallback_sink)); + + pa_dbus_send_empty_reply(conn, msg); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_sources(pa_dbusiface_core *c, unsigned *n) { + const char **sources; + unsigned i; + void *state = NULL; + pa_dbusiface_device *source; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->sources_by_index); + + if (*n == 0) + return NULL; + + sources = pa_xnew(const char *, *n); + + for (i = 0, source = pa_hashmap_iterate(c->sources_by_index, &state, NULL); source; ++i, source = pa_hashmap_iterate(c->sources_by_index, &state, NULL)) + sources[i] = pa_dbusiface_device_get_path(source); + + pa_assert(i == *n); + + return sources; +} + +static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **sources; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + sources = get_sources(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, sources, n); + + pa_xfree(sources); +} + +static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + pa_dbusiface_device *fallback_source; + const char *object_path; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (!c->fallback_source) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sources, and therefore no fallback source either."); + return; + } + + pa_assert_se((fallback_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index)))); + object_path = pa_dbusiface_device_get_path(fallback_source); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); +} + +static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + pa_dbusiface_device *fallback_source; + const char *object_path; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (!c->fallback_source) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sources, and therefore no fallback source either."); + return; + } + + if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path) < 0) + return; + + if (!(fallback_source = pa_hashmap_get(c->sources_by_path, object_path))) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such source."); + return; + } + + pa_namereg_set_default_source(c->core, pa_dbusiface_device_get_source(fallback_source)); + + pa_dbus_send_empty_reply(conn, msg); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_playback_streams(pa_dbusiface_core *c, unsigned *n) { + const char **streams; + unsigned i; + void *state = NULL; + pa_dbusiface_stream *stream; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->playback_streams); + + if (*n == 0) + return NULL; + + streams = pa_xnew(const char *, *n); + + for (i = 0, stream = pa_hashmap_iterate(c->playback_streams, &state, NULL); stream; ++i, stream = pa_hashmap_iterate(c->playback_streams, &state, NULL)) + streams[i] = pa_dbusiface_stream_get_path(stream); + + pa_assert(i == *n); + + return streams; +} + +static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **playback_streams; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + playback_streams = get_playback_streams(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, playback_streams, n); + + pa_xfree(playback_streams); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_record_streams(pa_dbusiface_core *c, unsigned *n) { + const char **streams; + unsigned i; + void *state = NULL; + pa_dbusiface_stream *stream; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->record_streams); + + if (*n == 0) + return NULL; + + streams = pa_xnew(const char *, *n); + + for (i = 0, stream = pa_hashmap_iterate(c->record_streams, &state, NULL); stream; ++i, stream = pa_hashmap_iterate(c->record_streams, &state, NULL)) + streams[i] = pa_dbusiface_stream_get_path(stream); + + pa_assert(i == *n); + + return streams; +} + +static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **record_streams; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + record_streams = get_record_streams(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, record_streams, n); + + pa_xfree(record_streams); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_samples(pa_dbusiface_core *c, unsigned *n) { + const char **samples; + unsigned i; + void *state = NULL; + pa_dbusiface_sample *sample; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->samples); + + if (*n == 0) + return NULL; + + samples = pa_xnew(const char *, *n); + + for (i = 0, sample = pa_hashmap_iterate(c->samples, &state, NULL); sample; ++i, sample = pa_hashmap_iterate(c->samples, &state, NULL)) + samples[i] = pa_dbusiface_sample_get_path(sample); + + pa_assert(i == *n); + + return samples; +} + +static void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **samples; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + samples = get_samples(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, samples, n); + + pa_xfree(samples); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_modules(pa_dbusiface_core *c, unsigned *n) { + const char **modules; + unsigned i; + void *state = NULL; + pa_dbusiface_module *module; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->modules); + + if (*n == 0) + return NULL; + + modules = pa_xnew(const char *, *n); + + for (i = 0, module = pa_hashmap_iterate(c->modules, &state, NULL); module; ++i, module = pa_hashmap_iterate(c->modules, &state, NULL)) + modules[i] = pa_dbusiface_module_get_path(module); + + pa_assert(i == *n); + + return modules; +} + +static void handle_get_modules(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **modules; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + modules = get_modules(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, modules, n); + + pa_xfree(modules); +} + +/* The caller frees the array, but not the strings. */ +static const char **get_clients(pa_dbusiface_core *c, unsigned *n) { + const char **clients; + unsigned i; + void *state = NULL; + pa_dbusiface_client *client; + + pa_assert(c); + pa_assert(n); + + *n = pa_hashmap_size(c->clients); + + if (*n == 0) + return NULL; + + clients = pa_xnew(const char *, *n); + + for (i = 0, client = pa_hashmap_iterate(c->clients, &state, NULL); client; ++i, client = pa_hashmap_iterate(c->clients, &state, NULL)) + clients[i] = pa_dbusiface_client_get_path(client); + + pa_assert(i == *n); + + return clients; +} + +static void handle_get_clients(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **clients; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + clients = get_clients(c, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, clients, n); + + pa_xfree(clients); +} + +static const char *get_my_client(pa_dbusiface_core *c, DBusConnection *conn) { + pa_client *my_client; + + pa_assert(c); + pa_assert(conn); + + pa_assert_se((my_client = pa_dbus_protocol_get_client(c->dbus_protocol, conn))); + + return pa_dbusiface_client_get_path(pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(my_client->index))); +} + +static void handle_get_my_client(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char *my_client; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + my_client = get_my_client(c, conn); + + pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &my_client); +} + +static void handle_get_extensions(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char **extensions; + unsigned n; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + extensions = pa_dbus_protocol_get_extensions(c->dbus_protocol, &n); + + pa_dbus_send_basic_array_variant_reply(conn, msg, DBUS_TYPE_STRING, extensions, n); + + pa_xfree(extensions); +} + +static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + DBusMessage *reply = NULL; + DBusMessageIter msg_iter; + DBusMessageIter dict_iter; + dbus_uint32_t interface_revision; + const char *server_name; + const char *version; + dbus_bool_t is_local; + char *username; + char *hostname; + dbus_uint32_t *default_channels; + unsigned n_default_channels; + dbus_uint32_t default_sample_format; + dbus_uint32_t default_sample_rate; + const char **cards; + unsigned n_cards; + const char **sinks; + unsigned n_sinks; + const char *fallback_sink; + const char **sources; + unsigned n_sources; + const char *fallback_source; + const char **playback_streams; + unsigned n_playback_streams; + const char **record_streams; + unsigned n_record_streams; + const char **samples; + unsigned n_samples; + const char **modules; + unsigned n_modules; + const char **clients; + unsigned n_clients; + const char *my_client; + const char **extensions; + unsigned n_extensions; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + interface_revision = INTERFACE_REVISION; + server_name = PACKAGE_NAME; + version = PACKAGE_VERSION; + is_local = get_is_local(conn); + username = pa_get_user_name_malloc(); + hostname = pa_get_host_name_malloc(); + default_channels = get_default_channels(c, &n_default_channels); + default_sample_format = c->core->default_sample_spec.format; + default_sample_rate = c->core->default_sample_spec.rate; + cards = get_cards(c, &n_cards); + sinks = get_sinks(c, &n_sinks); + fallback_sink = c->fallback_sink ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index))) : NULL; + sources = get_sources(c, &n_sources); + fallback_source = c->fallback_source ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index))) : NULL; + playback_streams = get_playback_streams(c, &n_playback_streams); + record_streams = get_record_streams(c, &n_record_streams); + samples = get_samples(c, &n_samples); + modules = get_modules(c, &n_modules); + clients = get_clients(c, &n_clients); + my_client = get_my_client(c, conn); + extensions = pa_dbus_protocol_get_extensions(c->dbus_protocol, &n_extensions); + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + 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_HANDLER_INTERFACE_REVISION].property_name, DBUS_TYPE_UINT32, &interface_revision); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_NAME].property_name, DBUS_TYPE_STRING, &server_name); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_VERSION].property_name, DBUS_TYPE_STRING, &version); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_IS_LOCAL].property_name, DBUS_TYPE_BOOLEAN, &is_local); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_USERNAME].property_name, DBUS_TYPE_STRING, &username); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_HOSTNAME].property_name, DBUS_TYPE_STRING, &hostname); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_CHANNELS].property_name, DBUS_TYPE_UINT32, default_channels, n_default_channels); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_FORMAT].property_name, DBUS_TYPE_UINT32, &default_sample_format); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_DEFAULT_SAMPLE_RATE].property_name, DBUS_TYPE_UINT32, &default_sample_rate); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CARDS].property_name, DBUS_TYPE_OBJECT_PATH, cards, n_cards); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SINKS].property_name, DBUS_TYPE_OBJECT_PATH, sinks, n_sinks); + + if (fallback_sink) + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_FALLBACK_SINK].property_name, DBUS_TYPE_OBJECT_PATH, &fallback_sink); + + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SOURCES].property_name, DBUS_TYPE_OBJECT_PATH, sources, n_sources); + + if (fallback_source) + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_FALLBACK_SOURCE].property_name, DBUS_TYPE_OBJECT_PATH, &fallback_source); + + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_PLAYBACK_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, playback_streams, n_playback_streams); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_RECORD_STREAMS].property_name, DBUS_TYPE_OBJECT_PATH, record_streams, n_record_streams); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_SAMPLES].property_name, DBUS_TYPE_OBJECT_PATH, samples, n_samples); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MODULES].property_name, DBUS_TYPE_OBJECT_PATH, modules, n_modules); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_CLIENTS].property_name, DBUS_TYPE_OBJECT_PATH, clients, n_clients); + pa_dbus_append_basic_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_MY_CLIENT].property_name, DBUS_TYPE_OBJECT_PATH, &my_client); + pa_dbus_append_basic_array_variant_dict_entry(&dict_iter, property_handlers[PROPERTY_HANDLER_EXTENSIONS].property_name, DBUS_TYPE_STRING, extensions, n_extensions); + + 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); + + pa_xfree(username); + pa_xfree(hostname); + pa_xfree(default_channels); + pa_xfree(cards); + pa_xfree(sinks); + pa_xfree(sources); + pa_xfree(playback_streams); + pa_xfree(record_streams); + pa_xfree(samples); + pa_xfree(modules); + pa_xfree(clients); + pa_xfree(extensions); +} + +static void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + char *card_name; + pa_card *card; + pa_dbusiface_card *dbus_card; + const char *object_path; + DBusError error; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + dbus_error_init(&error); + + if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &card_name, DBUS_TYPE_INVALID)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + dbus_error_free(&error); + return; + } + + if (!(card = pa_namereg_get(c->core, card_name, PA_NAMEREG_CARD))) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such card."); + return; + } + + pa_assert_se((dbus_card = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(card->index)))); + + object_path = pa_dbusiface_card_get_path(dbus_card); + + pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); +} + +static void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + char *sink_name; + pa_sink *sink; + pa_dbusiface_device *dbus_sink; + const char *object_path; + DBusError error; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + dbus_error_init(&error); + + if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &sink_name, DBUS_TYPE_INVALID)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + dbus_error_free(&error); + return; + } + + if (!(sink = pa_namereg_get(c->core, sink_name, PA_NAMEREG_SINK))) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sink."); + return; + } + + pa_assert_se((dbus_sink = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(sink->index)))); + + object_path = pa_dbusiface_device_get_path(dbus_sink); + + pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); +} + +static void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + char *source_name; + pa_source *source; + pa_dbusiface_device *dbus_source; + const char *object_path; + DBusError error; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + dbus_error_init(&error); + + if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &source_name, DBUS_TYPE_INVALID)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + dbus_error_free(&error); + return; + } + + if (!(source = pa_namereg_get(c->core, source_name, PA_NAMEREG_SOURCE))) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such source."); + return; + } + + pa_assert_se((dbus_source = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(source->index)))); + + object_path = pa_dbusiface_device_get_path(dbus_source); + + pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); +} + +static void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + char *sample_name; + pa_scache_entry *sample; + pa_dbusiface_sample *dbus_sample; + const char *object_path; + DBusError error; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + dbus_error_init(&error); + + if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &sample_name, DBUS_TYPE_INVALID)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + dbus_error_free(&error); + return; + } + + if (!(sample = pa_namereg_get(c->core, sample_name, PA_NAMEREG_SAMPLE))) { + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sample."); + return; + } + + pa_assert_se((dbus_sample = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(sample->index)))); + + object_path = pa_dbusiface_sample_get_path(dbus_sample); + + pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); +} + +static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + DBusMessageIter msg_iter; + const char *name; + dbus_uint32_t sample_format; + dbus_uint32_t sample_rate; + const dbus_uint32_t *channels; + unsigned n_channels; + const dbus_uint32_t *default_volume; + unsigned n_volume_entries; + pa_proplist *property_list; + const uint8_t *data; + unsigned data_length; + unsigned i; + pa_sample_spec ss; + pa_channel_map map; + pa_memchunk chunk; + uint32_t idx; + pa_dbusiface_sample *dbus_sample = NULL; + pa_scache_entry *sample = NULL; + const char *object_path; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + chunk.memblock = NULL; + + if (!dbus_message_iter_init(msg, &msg_iter)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments."); + return; + } + + if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_STRING, &name) < 0) + return; + + if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &sample_format) < 0) + return; + + if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &sample_rate) < 0) + return; + + if (pa_dbus_get_fixed_array_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &channels, &n_channels) < 0) + return; + + if (pa_dbus_get_fixed_array_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &default_volume, &n_volume_entries) < 0) + return; + + if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter))) + return; + + if (pa_dbus_get_fixed_array_arg(conn, msg, &msg_iter, DBUS_TYPE_BYTE, &data, &data_length) < 0) + goto finish; + + if (sample_format >= PA_SAMPLE_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); + goto finish; + } + + if (sample_rate <= 0 || sample_rate > PA_RATE_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate."); + goto finish; + } + + if (n_channels == 0) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel map."); + goto finish; + } + + if (n_channels > PA_CHANNELS_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too many channels."); + goto finish; + } + + for (i = 0; i < n_channels; ++i) { + if (channels[i] >= PA_CHANNEL_POSITION_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position."); + goto finish; + } + } + + if (n_volume_entries != 0 && n_volume_entries != n_channels) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "The channels and default_volume arguments have different number of elements."); + goto finish; + } + + for (i = 0; i < n_volume_entries; ++i) { + if (default_volume[i] > PA_VOLUME_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume."); + goto finish; + } + } + + if (data_length == 0) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty data."); + goto finish; + } + + if (data_length > PA_SCACHE_ENTRY_SIZE_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too big sample."); + goto finish; + } + + ss.format = sample_format; + ss.rate = sample_rate; + ss.channels = n_channels; + + if (!pa_frame_aligned(data_length, &ss)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "The sample length in bytes doesn't align with the sample format and channels."); + goto finish; + } + + map.channels = n_channels; + for (i = 0; i < n_channels; ++i) + map.map[i] = channels[i]; + + chunk.memblock = pa_memblock_new(c->core->mempool, data_length); + chunk.index = 0; + chunk.length = data_length; + + memcpy(pa_memblock_acquire(chunk.memblock), data, data_length); + pa_memblock_release(chunk.memblock); + + if (pa_scache_add_item(c->core, name, &ss, &map, &chunk, property_list, &idx) < 0) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Adding the sample failed."); + goto finish; + } + + sample = pa_idxset_get_by_index(c->core->scache, idx); + + if (n_volume_entries > 0) { + sample->volume.channels = n_channels; + for (i = 0; i < n_volume_entries; ++i) + sample->volume.values[i] = default_volume[i]; + sample->volume_is_set = TRUE; + } else { + sample->volume_is_set = FALSE; + } + + dbus_sample = pa_dbusiface_sample_new(sample, OBJECT_PATH); + pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), dbus_sample); + + object_path = pa_dbusiface_sample_get_path(dbus_sample); + + pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); + +finish: + if (property_list) + pa_proplist_free(property_list); + + if (chunk.memblock) + pa_memblock_unref(chunk.memblock); +} + +static pa_bool_t contains_space(const char *string) { + const char *p; + + pa_assert(string); + + for (p = string; *p; ++p) { + if (isspace(*p)) + return TRUE; + } + + return FALSE; +} + +static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + DBusMessageIter msg_iter; + DBusMessageIter dict_iter; + char *name; + const char *key; + const char *value; + char *escaped_value; + pa_strbuf *arg_buffer = NULL; + pa_module *module; + pa_dbusiface_module *dbus_module; + const char *object_path; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (c->core->disallow_module_loading) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "The server is configured to disallow module loading."); + return; + } + + if (!dbus_message_iter_init(msg, &msg_iter)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments."); + return; + } + + if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_STRING, &name) < 0) + return; + + if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_ARRAY) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong argument type or too few arguments. An array was expected."); + return; + } + + if (dbus_message_iter_get_element_type(&msg_iter) != DBUS_TYPE_DICT_ENTRY) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong array element type. A dict entry was expected."); + return; + } + + arg_buffer = pa_strbuf_new(); + + dbus_message_iter_recurse(&msg_iter, &dict_iter); + + while (dbus_message_iter_has_next(&dict_iter)) { + if (!pa_strbuf_isempty(arg_buffer)) + pa_strbuf_putc(arg_buffer, ' '); + + if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict key type. A string was expected."); + goto finish; + } + + dbus_message_iter_get_basic(&dict_iter, &key); + + if (strlen(key) <= 0 || !pa_ascii_valid(key) || contains_space(key)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid module argument name."); + goto finish; + } + + if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict value type. A string was expected."); + goto finish; + } + + dbus_message_iter_get_basic(&dict_iter, &value); + + escaped_value = pa_escape(value, "\""); + pa_strbuf_printf(arg_buffer, "%s=\"%s\"", key, escaped_value); + pa_xfree(escaped_value); + } + + if (!(module = pa_module_load(c->core, name, pa_strbuf_tostring(arg_buffer)))) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Failed to load module."); + goto finish; + } + + dbus_module = pa_dbusiface_module_new(module, OBJECT_PATH); + pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(module->index), dbus_module); + + object_path = pa_dbusiface_module_get_path(dbus_module); + + pa_dbus_send_basic_value_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); + +finish: + if (arg_buffer) + pa_strbuf_free(arg_buffer); +} + +static void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + if (c->core->disallow_exit) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_ACCESS_DENIED, "The server is configured to disallow exiting."); + return; + } + + pa_dbus_send_empty_reply(conn, msg); + + pa_core_exit(c->core, FALSE, 0); +} + +static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char *signal; + char **objects = NULL; + int n_objects; + DBusError error; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + dbus_error_init(&error); + + if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &signal, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, DBUS_TYPE_INVALID)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + dbus_error_free(&error); + goto finish; + } + + pa_dbus_protocol_add_signal_listener(c->dbus_protocol, conn, *signal ? signal : NULL, objects, n_objects); + + pa_dbus_send_empty_reply(conn, msg); + +finish: + dbus_free_string_array(objects); +} + +static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_dbusiface_core *c = userdata; + const char *signal; + DBusError error; + + pa_assert(conn); + pa_assert(msg); + pa_assert(c); + + dbus_error_init(&error); + + if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &signal, DBUS_TYPE_INVALID)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + dbus_error_free(&error); + return; + } + + pa_dbus_protocol_remove_signal_listener(c->dbus_protocol, conn, *signal ? signal : NULL); + + pa_dbus_send_empty_reply(conn, msg); +} + +static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { + pa_dbusiface_core *c = userdata; + pa_dbusiface_card *card = NULL; + pa_dbusiface_device *device = NULL; + pa_dbusiface_stream *stream = NULL; + pa_dbusiface_sample *sample = NULL; + pa_dbusiface_module *module = NULL; + pa_dbusiface_client *client = NULL; + DBusMessage *signal = NULL; + const char *object_path = NULL; + pa_sink *new_fallback_sink = NULL; + pa_source *new_fallback_source = NULL; + + pa_assert(c); + + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_SERVER: + new_fallback_sink = pa_namereg_get_default_sink(core); + new_fallback_source = pa_namereg_get_default_source(core); + + if (c->fallback_sink != new_fallback_sink) { + c->fallback_sink = new_fallback_sink; + + if (new_fallback_sink) { + pa_assert_se((device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))); + + object_path = pa_dbusiface_device_get_path(device); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; + } + } + + if (c->fallback_source != new_fallback_source) { + c->fallback_source = new_fallback_source; + + if (new_fallback_source) { + pa_assert_se((device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))); + + object_path = pa_dbusiface_device_get_path(device); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; + } + } + break; + + case PA_SUBSCRIPTION_EVENT_CARD: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + card = pa_dbusiface_card_new(pa_idxset_get_by_index(core->cards, idx), OBJECT_PATH); + pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), card); + + object_path = pa_dbusiface_card_get_path(card); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_CARD].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((card = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(idx)))); + + object_path = pa_dbusiface_card_get_path(card); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_CARD_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_card_free(card); + } + break; + + case PA_SUBSCRIPTION_EVENT_SINK: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + device = pa_dbusiface_device_new_sink(pa_idxset_get_by_index(core->sinks, idx), OBJECT_PATH); + object_path = pa_dbusiface_device_get_path(device); + + pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); + pa_hashmap_put(c->sinks_by_path, object_path, device); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SINK].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((device = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))); + object_path = pa_dbusiface_device_get_path(device); + pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path)); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_SINK_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_device_free(device); + } + break; + + case PA_SUBSCRIPTION_EVENT_SOURCE: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + device = pa_dbusiface_device_new_source(pa_idxset_get_by_index(core->sources, idx), OBJECT_PATH); + object_path = pa_dbusiface_device_get_path(device); + + pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); + pa_hashmap_put(c->sources_by_path, object_path, device); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SOURCE].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((device = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(idx)))); + object_path = pa_dbusiface_device_get_path(device); + pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path)); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_SOURCE_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_device_free(device); + } + break; + + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + stream = pa_dbusiface_stream_new_playback(pa_idxset_get_by_index(core->sink_inputs, idx), OBJECT_PATH); + pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream); + + object_path = pa_dbusiface_stream_get_path(stream); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((stream = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx)))); + + object_path = pa_dbusiface_stream_get_path(stream); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_stream_free(stream); + } + break; + + case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + stream = pa_dbusiface_stream_new_record(pa_idxset_get_by_index(core->source_outputs, idx), OBJECT_PATH); + pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream); + + object_path = pa_dbusiface_stream_get_path(stream); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_RECORD_STREAM].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((stream = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx)))); + + object_path = pa_dbusiface_stream_get_path(stream); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_RECORD_STREAM_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_stream_free(stream); + } + break; + + case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + /* We may have created the pa_dbusiface_sample object already + * in handle_upload_sample. */ + if (!(sample = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(idx)))) { + sample = pa_dbusiface_sample_new(pa_idxset_get_by_index(core->scache, idx), OBJECT_PATH); + pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), sample); + } + + object_path = pa_dbusiface_sample_get_path(sample); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SAMPLE].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((sample = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx)))); + + object_path = pa_dbusiface_sample_get_path(sample); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_SAMPLE_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_sample_free(sample); + } + break; + + case PA_SUBSCRIPTION_EVENT_MODULE: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + /* We may have created the pa_dbusiface_module object already + * in handle_load_module. */ + if (!(module = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) { + module = pa_dbusiface_module_new(pa_idxset_get_by_index(core->modules, idx), OBJECT_PATH); + pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module); + } + + object_path = pa_dbusiface_module_get_path(module); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_MODULE].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((module = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx)))); + + object_path = pa_dbusiface_module_get_path(module); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_MODULE_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_module_free(module); + } + break; + + case PA_SUBSCRIPTION_EVENT_CLIENT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + client = pa_dbusiface_client_new(pa_idxset_get_by_index(core->clients, idx), OBJECT_PATH); + pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), client); + + object_path = pa_dbusiface_client_get_path(client); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_CLIENT].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + pa_assert_se((client = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(idx)))); + + object_path = pa_dbusiface_client_get_path(client); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_CLIENT_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbusiface_client_free(client); + } + break; + } + + if (signal) { + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + } +} + +pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { + pa_dbusiface_core *c; + pa_card *card; + pa_sink *sink; + pa_source *source; + pa_dbusiface_device *device; + pa_sink_input *sink_input; + pa_source_output *source_output; + pa_scache_entry *sample; + pa_module *module; + pa_client *client; + uint32_t idx; + + pa_assert(core); + + c = pa_xnew(pa_dbusiface_core, 1); + c->core = core; + c->subscription = pa_subscription_new(core, PA_SUBSCRIPTION_MASK_ALL, subscription_cb, c); + c->dbus_protocol = pa_dbus_protocol_get(core); + c->cards = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->sinks_by_index = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->sinks_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + c->sources_by_index = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->sources_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->samples = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->modules = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->clients = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + c->fallback_sink = pa_namereg_get_default_sink(core); + c->fallback_source = pa_namereg_get_default_source(core); + + for (card = pa_idxset_first(core->cards, &idx); card; card = pa_idxset_next(core->cards, &idx)) + pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(card, OBJECT_PATH)); + + for (sink = pa_idxset_first(core->sinks, &idx); sink; sink = pa_idxset_next(core->sinks, &idx)) { + device = pa_dbusiface_device_new_sink(sink, OBJECT_PATH); + pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); + pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device); + } + + for (source = pa_idxset_first(core->sources, &idx); source; source = pa_idxset_next(core->sources, &idx)) { + device = pa_dbusiface_device_new_source(source, OBJECT_PATH); + pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); + pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device); + } + + for (sink_input = pa_idxset_first(core->sink_inputs, &idx); sink_input; sink_input = pa_idxset_next(core->sink_inputs, &idx)) + pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_playback(sink_input, OBJECT_PATH)); + + for (source_output = pa_idxset_first(core->source_outputs, &idx); source_output; source_output = pa_idxset_next(core->source_outputs, &idx)) + pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_record(source_output, OBJECT_PATH)); + + for (sample = pa_idxset_first(core->scache, &idx); sample; sample = pa_idxset_next(core->scache, &idx)) + pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), pa_dbusiface_sample_new(sample, OBJECT_PATH)); + + for (module = pa_idxset_first(core->modules, &idx); module; module = pa_idxset_next(core->modules, &idx)) + pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(module, OBJECT_PATH)); + + for (client = pa_idxset_first(core->clients, &idx); client; client = pa_idxset_next(core->clients, &idx)) + pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(client, OBJECT_PATH)); + + pa_dbus_protocol_add_interface(c->dbus_protocol, OBJECT_PATH, &core_interface_info, c); + + return c; +} + +static void free_card_cb(void *p, void *userdata) { + pa_dbusiface_card *c = p; + + pa_assert(c); + + pa_dbusiface_card_free(c); +} + +static void free_device_cb(void *p, void *userdata) { + pa_dbusiface_device *d = p; + + pa_assert(d); + + pa_dbusiface_device_free(d); +} + +static void free_stream_cb(void *p, void *userdata) { + pa_dbusiface_stream *s = p; + + pa_assert(s); + + pa_dbusiface_stream_free(s); +} + +static void free_sample_cb(void *p, void *userdata) { + pa_dbusiface_sample *s = p; + + pa_assert(s); + + pa_dbusiface_sample_free(s); +} + +static void free_module_cb(void *p, void *userdata) { + pa_dbusiface_module *m = p; + + pa_assert(m); + + pa_dbusiface_module_free(m); +} + +static void free_client_cb(void *p, void *userdata) { + pa_dbusiface_client *c = p; + + pa_assert(c); + + pa_dbusiface_client_free(c); +} + +void pa_dbusiface_core_free(pa_dbusiface_core *c) { + pa_assert(c); + + pa_dbus_protocol_remove_interface(c->dbus_protocol, OBJECT_PATH, INTERFACE_CORE); + + pa_subscription_free(c->subscription); + pa_hashmap_free(c->cards, free_card_cb, NULL); + pa_hashmap_free(c->sinks_by_index, free_device_cb, NULL); + pa_hashmap_free(c->sinks_by_path, NULL, NULL); + pa_hashmap_free(c->sources_by_index, free_device_cb, NULL); + pa_hashmap_free(c->sources_by_path, NULL, NULL); + pa_hashmap_free(c->playback_streams, free_stream_cb, NULL); + pa_hashmap_free(c->record_streams, free_stream_cb, NULL); + pa_hashmap_free(c->samples, free_sample_cb, NULL); + pa_hashmap_free(c->modules, free_module_cb, NULL); + pa_hashmap_free(c->clients, free_client_cb, NULL); + + pa_dbus_protocol_unref(c->dbus_protocol); + + pa_xfree(c); +} -- cgit From 018810ec9a96d63446bdc9a82d6c931779f7a97d Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Mon, 27 Jul 2009 20:01:39 +0300 Subject: Bug fixing and minor cleanups. --- src/modules/dbus/iface-core.c | 95 ++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 51 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 31f12603..d17499c1 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -220,7 +220,7 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { .receive_cb = handle_upload_sample }, [METHOD_HANDLER_LOAD_MODULE] = { .method_name = "LoadModule", - .arguments = upload_sample_args, + .arguments = load_module_args, .n_arguments = sizeof(load_module_args) / sizeof(pa_dbus_arg_info), .receive_cb = handle_load_module }, [METHOD_HANDLER_EXIT] = { @@ -424,11 +424,8 @@ static void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_dbusiface_core *c = userdata; pa_channel_map new_channel_map; - DBusMessageIter msg_iter; - DBusMessageIter variant_iter; - DBusMessageIter array_iter; dbus_uint32_t *default_channels; - int n_channels; + unsigned n_channels; unsigned i; pa_assert(conn); @@ -437,37 +434,16 @@ static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, pa_channel_map_init(&new_channel_map); - pa_assert_se(dbus_message_iter_init(msg, &msg_iter)); - - /* Skip the interface and property name arguments. */ - if (!dbus_message_iter_next(&msg_iter) || !dbus_message_iter_next(&msg_iter)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments."); + if (pa_dbus_get_fixed_array_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &default_channels, &n_channels) < 0) return; - } - - if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_VARIANT) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Message argument isn't a variant."); - return; - } - - dbus_message_iter_recurse(&msg_iter, &variant_iter); - - if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Variant doesn't contain an array."); - return; - } - dbus_message_iter_recurse(&variant_iter, &array_iter); - - if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_UINT32) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Array type is not uint32."); + if (n_channels <= 0) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel array."); return; } - dbus_message_iter_get_fixed_array(&array_iter, &default_channels, &n_channels); - - if (n_channels <= 0) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel array."); + if (n_channels > PA_CHANNELS_MAX) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too many channels: %u. The maximum number of channels is %u.", n_channels, PA_CHANNELS_MAX); return; } @@ -475,7 +451,7 @@ static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, for (i = 0; i < new_channel_map.channels; ++i) { if (default_channels[i] >= PA_CHANNEL_POSITION_MAX) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid channel position: %u.", default_channels[i]); return; } @@ -547,7 +523,7 @@ static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *ms return; if (default_sample_rate <= 0 || default_sample_rate > PA_RATE_MAX) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate."); return; } @@ -1149,7 +1125,7 @@ static void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void dbus_error_init(&error); if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &card_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); dbus_error_free(&error); return; } @@ -1181,7 +1157,7 @@ static void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void dbus_error_init(&error); if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &sink_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); dbus_error_free(&error); return; } @@ -1213,7 +1189,7 @@ static void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, vo dbus_error_init(&error); if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &source_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); dbus_error_free(&error); return; } @@ -1245,7 +1221,7 @@ static void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, vo dbus_error_init(&error); if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &sample_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); dbus_error_free(&error); return; } @@ -1433,6 +1409,7 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use pa_dbusiface_core *c = userdata; DBusMessageIter msg_iter; DBusMessageIter dict_iter; + DBusMessageIter dict_entry_iter; char *name; const char *key; const char *value; @@ -1441,6 +1418,7 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use pa_module *module; pa_dbusiface_module *dbus_module; const char *object_path; + int arg_type; pa_assert(conn); pa_assert(msg); @@ -1459,13 +1437,18 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_STRING, &name) < 0) return; - if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_ARRAY) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong argument type or too few arguments. An array was expected."); + arg_type = dbus_message_iter_get_arg_type(&msg_iter); + if (arg_type != DBUS_TYPE_ARRAY) { + if (arg_type == DBUS_TYPE_INVALID) + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments. A dictionary from strings to strings was expected."); + else + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong argument type: '%c'. An dictionary from strings to strings was expected.", (char) arg_type); return; } - if (dbus_message_iter_get_element_type(&msg_iter) != DBUS_TYPE_DICT_ENTRY) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong array element type. A dict entry was expected."); + arg_type = dbus_message_iter_get_element_type(&msg_iter); + if (arg_type != DBUS_TYPE_DICT_ENTRY) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong array element type: '%c'. A dict entry (string to string) was expected.", (char) arg_type); return; } @@ -1473,28 +1456,38 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use dbus_message_iter_recurse(&msg_iter, &dict_iter); - while (dbus_message_iter_has_next(&dict_iter)) { + while (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID) { if (!pa_strbuf_isempty(arg_buffer)) pa_strbuf_putc(arg_buffer, ' '); - if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict key type. A string was expected."); + dbus_message_iter_recurse(&dict_iter, &dict_entry_iter); + + arg_type = dbus_message_iter_get_arg_type(&dict_entry_iter); + if (arg_type != DBUS_TYPE_STRING) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict key type: '%c'. A string was expected.", (char) arg_type); goto finish; } - dbus_message_iter_get_basic(&dict_iter, &key); + dbus_message_iter_get_basic(&dict_entry_iter, &key); + dbus_message_iter_next(&dict_entry_iter); if (strlen(key) <= 0 || !pa_ascii_valid(key) || contains_space(key)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid module argument name."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid module argument name: %s", key); goto finish; } - if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict value type. A string was expected."); + arg_type = dbus_message_iter_get_arg_type(&dict_entry_iter); + if (arg_type != DBUS_TYPE_STRING) { + if (arg_type == DBUS_TYPE_INVALID) + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Dict value missing."); + else + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict value type: '%c'. A string was expected.", (char) arg_type); goto finish; } - dbus_message_iter_get_basic(&dict_iter, &value); + dbus_message_iter_get_basic(&dict_entry_iter, &value); + + dbus_message_iter_next(&dict_iter); escaped_value = pa_escape(value, "\""); pa_strbuf_printf(arg_buffer, "%s=\"%s\"", key, escaped_value); @@ -1549,7 +1542,7 @@ static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, voi dbus_error_init(&error); if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &signal, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); dbus_error_free(&error); goto finish; } @@ -1574,7 +1567,7 @@ static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage * dbus_error_init(&error); if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &signal, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, error.message); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); dbus_error_free(&error); return; } -- cgit From b061957e57f74d7aa51bde9d24dd5e5c75af9497 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Thu, 30 Jul 2009 13:11:32 +0300 Subject: dbus/iface-core.c: Make sure D-Bus objects are created only once. --- src/modules/dbus/iface-core.c | 48 +++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index d17499c1..cdfd2a3c 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -1632,8 +1632,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_CARD: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - card = pa_dbusiface_card_new(pa_idxset_get_by_index(core->cards, idx), OBJECT_PATH); - pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), card); + if (!(card = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(idx)))) { + card = pa_dbusiface_card_new(pa_idxset_get_by_index(core->cards, idx), OBJECT_PATH); + pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), card); + } object_path = pa_dbusiface_card_get_path(card); @@ -1654,11 +1656,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SINK: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - device = pa_dbusiface_device_new_sink(pa_idxset_get_by_index(core->sinks, idx), OBJECT_PATH); - object_path = pa_dbusiface_device_get_path(device); + if (!(device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))) { + device = pa_dbusiface_device_new_sink(pa_idxset_get_by_index(core->sinks, idx), OBJECT_PATH); + pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); + pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device); + } - pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); - pa_hashmap_put(c->sinks_by_path, object_path, device); + object_path = pa_dbusiface_device_get_path(device); pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SINK].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); @@ -1677,11 +1681,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SOURCE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - device = pa_dbusiface_device_new_source(pa_idxset_get_by_index(core->sources, idx), OBJECT_PATH); - object_path = pa_dbusiface_device_get_path(device); + if (!(device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(idx)))) { + device = pa_dbusiface_device_new_source(pa_idxset_get_by_index(core->sources, idx), OBJECT_PATH); + pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); + pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device); + } - pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); - pa_hashmap_put(c->sources_by_path, object_path, device); + object_path = pa_dbusiface_device_get_path(device); pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SOURCE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); @@ -1700,8 +1706,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SINK_INPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - stream = pa_dbusiface_stream_new_playback(pa_idxset_get_by_index(core->sink_inputs, idx), OBJECT_PATH); - pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream); + if (!(stream = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(idx)))) { + stream = pa_dbusiface_stream_new_playback(pa_idxset_get_by_index(core->sink_inputs, idx), OBJECT_PATH); + pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream); + } object_path = pa_dbusiface_stream_get_path(stream); @@ -1722,8 +1730,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - stream = pa_dbusiface_stream_new_record(pa_idxset_get_by_index(core->source_outputs, idx), OBJECT_PATH); - pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream); + if (!(stream = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(idx)))) { + stream = pa_dbusiface_stream_new_record(pa_idxset_get_by_index(core->source_outputs, idx), OBJECT_PATH); + pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream); + } object_path = pa_dbusiface_stream_get_path(stream); @@ -1744,8 +1754,6 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - /* We may have created the pa_dbusiface_sample object already - * in handle_upload_sample. */ if (!(sample = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(idx)))) { sample = pa_dbusiface_sample_new(pa_idxset_get_by_index(core->scache, idx), OBJECT_PATH); pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), sample); @@ -1770,8 +1778,6 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_MODULE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - /* We may have created the pa_dbusiface_module object already - * in handle_load_module. */ if (!(module = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) { module = pa_dbusiface_module_new(pa_idxset_get_by_index(core->modules, idx), OBJECT_PATH); pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module); @@ -1796,8 +1802,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_CLIENT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - client = pa_dbusiface_client_new(pa_idxset_get_by_index(core->clients, idx), OBJECT_PATH); - pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), client); + if (!(client = pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(idx)))) { + client = pa_dbusiface_client_new(pa_idxset_get_by_index(core->clients, idx), OBJECT_PATH); + pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), client); + } object_path = pa_dbusiface_client_get_path(client); -- cgit From 68cb63c0d9b1493ebc4274f9ea1fb05a8c273574 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Fri, 31 Jul 2009 12:06:53 +0300 Subject: dbusiface-core: Send signals whenever extensions are registered and unregistered. --- src/modules/dbus/iface-core.c | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index cdfd2a3c..e2e3be2c 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -112,6 +112,9 @@ struct pa_dbusiface_core { pa_sink *fallback_sink; pa_source *fallback_source; + + pa_hook_slot *extension_registered_slot; + pa_hook_slot *extension_unregistered_slot; }; enum property_handler_index { @@ -259,6 +262,8 @@ enum signal_index { SIGNAL_MODULE_REMOVED, SIGNAL_NEW_CLIENT, SIGNAL_CLIENT_REMOVED, + SIGNAL_NEW_EXTENSION, + SIGNAL_EXTENSION_REMOVED, SIGNAL_MAX }; @@ -280,6 +285,8 @@ static pa_dbus_arg_info new_module_args[] = { { "module", static pa_dbus_arg_info module_removed_args[] = { { "module", "o", NULL } }; static pa_dbus_arg_info new_client_args[] = { { "client", "o", NULL } }; static pa_dbus_arg_info client_removed_args[] = { { "client", "o", NULL } }; +static pa_dbus_arg_info new_extension_args[] = { { "extension", "s", NULL } }; +static pa_dbus_arg_info extension_removed_args[] = { { "extension", "s", NULL } }; static pa_dbus_signal_info signals[SIGNAL_MAX] = { [SIGNAL_NEW_CARD] = { .name = "NewCard", .arguments = new_card_args, .n_arguments = 1 }, @@ -300,6 +307,8 @@ static pa_dbus_signal_info signals[SIGNAL_MAX] = { [SIGNAL_MODULE_REMOVED] = { .name = "ModuleRemoved", .arguments = module_removed_args, .n_arguments = 1 }, [SIGNAL_NEW_CLIENT] = { .name = "NewClient", .arguments = new_client_args, .n_arguments = 1 }, [SIGNAL_CLIENT_REMOVED] = { .name = "ClientRemoved", .arguments = client_removed_args, .n_arguments = 1 }, + [SIGNAL_NEW_EXTENSION] = { .name = "NewExtension", .arguments = new_extension_args, .n_arguments = 1 }, + [SIGNAL_EXTENSION_REMOVED] = { .name = "ExtensionRemoved", .arguments = extension_removed_args, .n_arguments = 1 } }; static pa_dbus_interface_info core_interface_info = { @@ -1831,6 +1840,40 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 } } +static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data, void *slot_data) { + pa_dbusiface_core *c = slot_data; + const char *ext_name = call_data; + DBusMessage *signal = NULL; + + pa_assert(c); + pa_assert(ext_name); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_EXTENSION].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); + + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + + return PA_HOOK_OK; +} + +static pa_hook_result_t extension_unregistered_cb(void *hook_data, void *call_data, void *slot_data) { + pa_dbusiface_core *c = slot_data; + const char *ext_name = call_data; + DBusMessage *signal = NULL; + + pa_assert(c); + pa_assert(ext_name); + + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_EXTENSION_REMOVED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); + + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + + return PA_HOOK_OK; +} + pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { pa_dbusiface_core *c; pa_card *card; @@ -1862,6 +1905,8 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { c->clients = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); c->fallback_sink = pa_namereg_get_default_sink(core); c->fallback_source = pa_namereg_get_default_source(core); + c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED, PA_HOOK_NORMAL, extension_registered_cb, c); + c->extension_unregistered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED, PA_HOOK_NORMAL, extension_unregistered_cb, c); for (card = pa_idxset_first(core->cards, &idx); card; card = pa_idxset_next(core->cards, &idx)) pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(card, OBJECT_PATH)); @@ -1962,6 +2007,8 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_hashmap_free(c->samples, free_sample_cb, NULL); pa_hashmap_free(c->modules, free_module_cb, NULL); pa_hashmap_free(c->clients, free_client_cb, NULL); + pa_hook_slot_free(c->extension_registered_slot); + pa_hook_slot_free(c->extension_unregistered_slot); pa_dbus_protocol_unref(c->dbus_protocol); -- cgit From a1ba80bc4e715b8ce77f55676bc63b02c1a82d3c Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sat, 1 Aug 2009 08:26:51 +0300 Subject: dbusiface-core: Don't die if we get a default sink/source change event before the new default device is actually created. --- src/modules/dbus/iface-core.c | 50 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 8 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index e2e3be2c..69c1bd25 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -1609,9 +1609,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (c->fallback_sink != new_fallback_sink) { c->fallback_sink = new_fallback_sink; - if (new_fallback_sink) { - pa_assert_se((device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))); - + if (new_fallback_sink && (device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { object_path = pa_dbusiface_device_get_path(device); pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); @@ -1625,9 +1623,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (c->fallback_source != new_fallback_source) { c->fallback_source = new_fallback_source; - if (new_fallback_source) { - pa_assert_se((device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))); - + if (new_fallback_source && (device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { object_path = pa_dbusiface_device_get_path(device); pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); @@ -1665,8 +1661,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SINK: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + pa_sink *sink = pa_idxset_get_by_index(core->sinks, idx); + if (!(device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))) { - device = pa_dbusiface_device_new_sink(pa_idxset_get_by_index(core->sinks, idx), OBJECT_PATH); + device = pa_dbusiface_device_new_sink(sink, OBJECT_PATH); pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device); } @@ -1676,6 +1674,23 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SINK].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; + + if (c->fallback_sink && pa_streq(c->fallback_sink->name, sink->name)) { + /* We have got default sink change event, but at that point + * the D-Bus sink object wasn't created yet. Now that the + * object is created, let's send the fallback sink change + * signal. */ + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; + } + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { pa_assert_se((device = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))); object_path = pa_dbusiface_device_get_path(device); @@ -1690,8 +1705,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SOURCE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + pa_source *source = pa_idxset_get_by_index(core->sources, idx); + if (!(device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(idx)))) { - device = pa_dbusiface_device_new_source(pa_idxset_get_by_index(core->sources, idx), OBJECT_PATH); + device = pa_dbusiface_device_new_source(source, OBJECT_PATH); pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device); } @@ -1701,6 +1718,23 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SOURCE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; + + if (c->fallback_source && pa_streq(c->fallback_source->name, source->name)) { + /* We have got default source change event, but at that + * point the D-Bus source object wasn't created yet. Now + * that the object is created, let's send the fallback + * source change signal. */ + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); + + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; + } + } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { pa_assert_se((device = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(idx)))); object_path = pa_dbusiface_device_get_path(device); -- cgit From 8966c61d3343e13502cfa210bb7123b7d7e7b27e Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 4 Aug 2009 17:50:18 +0300 Subject: dbusiface-core: Make the interface string a public constant. --- src/modules/dbus/iface-core.c | 49 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 69c1bd25..695e4a3c 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -48,7 +48,6 @@ #include "iface-core.h" #define OBJECT_PATH "/org/pulseaudio/core1" -#define INTERFACE_CORE "org.PulseAudio.Core1" #define INTERFACE_REVISION 0 @@ -312,7 +311,7 @@ static pa_dbus_signal_info signals[SIGNAL_MAX] = { }; static pa_dbus_interface_info core_interface_info = { - .name = INTERFACE_CORE, + .name = PA_DBUSIFACE_CORE_INTERFACE, .method_handlers = method_handlers, .n_method_handlers = METHOD_HANDLER_MAX, .property_handlers = property_handlers, @@ -1612,7 +1611,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (new_fallback_sink && (device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); @@ -1626,7 +1625,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (new_fallback_source && (device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); @@ -1644,7 +1643,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_card_get_path(card); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_CARD].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_CARD].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1652,7 +1651,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_card_get_path(card); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_CARD_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_CARD_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_card_free(card); @@ -1671,7 +1670,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SINK].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_SINK].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1683,7 +1682,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 * the D-Bus sink object wasn't created yet. Now that the * object is created, let's send the fallback sink change * signal. */ - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1696,7 +1695,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_SINK_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_SINK_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device); @@ -1715,7 +1714,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SOURCE].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_SOURCE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1727,7 +1726,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 * point the D-Bus source object wasn't created yet. Now * that the object is created, let's send the fallback * source change signal. */ - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1740,7 +1739,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_SOURCE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_SOURCE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device); @@ -1756,7 +1755,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1764,7 +1763,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream); @@ -1780,7 +1779,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_RECORD_STREAM].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_RECORD_STREAM].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1788,7 +1787,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_RECORD_STREAM_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_RECORD_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream); @@ -1804,7 +1803,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_sample_get_path(sample); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_SAMPLE].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_SAMPLE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1812,7 +1811,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_sample_get_path(sample); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_SAMPLE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_SAMPLE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_sample_free(sample); @@ -1828,7 +1827,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_module_get_path(module); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_MODULE].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_MODULE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1836,7 +1835,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_module_get_path(module); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_MODULE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_MODULE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_module_free(module); @@ -1852,7 +1851,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_client_get_path(client); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_CLIENT].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_CLIENT].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1860,7 +1859,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_client_get_path(client); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_CLIENT_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_CLIENT_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_client_free(client); @@ -1882,7 +1881,7 @@ static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_NEW_EXTENSION].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_EXTENSION].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1899,7 +1898,7 @@ static pa_hook_result_t extension_unregistered_cb(void *hook_data, void *call_da pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, INTERFACE_CORE, signals[SIGNAL_EXTENSION_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_EXTENSION_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -2028,7 +2027,7 @@ static void free_client_cb(void *p, void *userdata) { void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_assert(c); - pa_dbus_protocol_remove_interface(c->dbus_protocol, OBJECT_PATH, INTERFACE_CORE); + pa_dbus_protocol_remove_interface(c->dbus_protocol, OBJECT_PATH, core_interface_info.name); pa_subscription_free(c->subscription); pa_hashmap_free(c->cards, free_card_cb, NULL); -- cgit From b1578e27b62e7332111bb706f79858b0866029e3 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 4 Aug 2009 17:55:10 +0300 Subject: dbus-protocol, dbusiface-core: Take a reference when storing the core pointer. --- src/modules/dbus/iface-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 695e4a3c..ca9ba582 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -1923,7 +1923,7 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { pa_assert(core); c = pa_xnew(pa_dbusiface_core, 1); - c->core = core; + c->core = pa_core_ref(core); c->subscription = pa_subscription_new(core, PA_SUBSCRIPTION_MASK_ALL, subscription_cb, c); c->dbus_protocol = pa_dbus_protocol_get(core); c->cards = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); @@ -2044,6 +2044,7 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_hook_slot_free(c->extension_unregistered_slot); pa_dbus_protocol_unref(c->dbus_protocol); + pa_core_unref(c->core); pa_xfree(c); } -- cgit From 44770c59e92f49288341afe8646d8bc39eb9f589 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 4 Aug 2009 18:01:26 +0300 Subject: dbusiface-memstats: Implement the Memstats D-Bus interface. --- src/modules/dbus/iface-core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index ca9ba582..ad729f93 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -41,6 +41,7 @@ #include "iface-card.h" #include "iface-client.h" #include "iface-device.h" +#include "iface-memstats.h" #include "iface-module.h" #include "iface-sample.h" #include "iface-stream.h" @@ -114,6 +115,8 @@ struct pa_dbusiface_core { pa_hook_slot *extension_registered_slot; pa_hook_slot *extension_unregistered_slot; + + pa_dbusiface_memstats *memstats; }; enum property_handler_index { @@ -1940,6 +1943,7 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { c->fallback_source = pa_namereg_get_default_source(core); c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED, PA_HOOK_NORMAL, extension_registered_cb, c); c->extension_unregistered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED, PA_HOOK_NORMAL, extension_unregistered_cb, c); + c->memstats = pa_dbusiface_memstats_new(core, OBJECT_PATH); for (card = pa_idxset_first(core->cards, &idx); card; card = pa_idxset_next(core->cards, &idx)) pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(card, OBJECT_PATH)); @@ -2042,6 +2046,7 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_hashmap_free(c->clients, free_client_cb, NULL); pa_hook_slot_free(c->extension_registered_slot); pa_hook_slot_free(c->extension_unregistered_slot); + pa_dbusiface_memstats_free(c->memstats); pa_dbus_protocol_unref(c->dbus_protocol); pa_core_unref(c->core); -- cgit From fcf68752e687123a171b1144f78f8eba1625a204 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 9 Aug 2009 08:37:33 +0300 Subject: dbus: Three entangled changes: * Make the dbus object constructors take a pa_dbusiface_core pointer as an argument. Remove the path_prefix argument. * Expose the core object path as a constant in protocol-dbus.h. * Move the core interface name constant from iface-core.h to protocol-dbus.h. --- src/modules/dbus/iface-core.c | 92 +++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 48 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index ad729f93..e40cb979 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -48,12 +48,8 @@ #include "iface-core.h" -#define OBJECT_PATH "/org/pulseaudio/core1" - #define INTERFACE_REVISION 0 - - static void handle_get_interface_revision(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_name(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_version(DBusConnection *conn, DBusMessage *msg, void *userdata); @@ -314,7 +310,7 @@ static pa_dbus_signal_info signals[SIGNAL_MAX] = { }; static pa_dbus_interface_info core_interface_info = { - .name = PA_DBUSIFACE_CORE_INTERFACE, + .name = PA_DBUS_CORE_INTERFACE, .method_handlers = method_handlers, .n_method_handlers = METHOD_HANDLER_MAX, .property_handlers = property_handlers, @@ -1388,7 +1384,7 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u sample->volume_is_set = FALSE; } - dbus_sample = pa_dbusiface_sample_new(sample, OBJECT_PATH); + dbus_sample = pa_dbusiface_sample_new(c, sample); pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), dbus_sample); object_path = pa_dbusiface_sample_get_path(dbus_sample); @@ -1510,7 +1506,7 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use goto finish; } - dbus_module = pa_dbusiface_module_new(module, OBJECT_PATH); + dbus_module = pa_dbusiface_module_new(c, module); pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(module->index), dbus_module); object_path = pa_dbusiface_module_get_path(dbus_module); @@ -1614,7 +1610,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (new_fallback_sink && (device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); @@ -1628,7 +1624,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (new_fallback_source && (device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); @@ -1640,13 +1636,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_CARD: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { if (!(card = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(idx)))) { - card = pa_dbusiface_card_new(pa_idxset_get_by_index(core->cards, idx), OBJECT_PATH); + card = pa_dbusiface_card_new(c, pa_idxset_get_by_index(core->cards, idx)); pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), card); } object_path = pa_dbusiface_card_get_path(card); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_CARD].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_CARD].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1654,7 +1650,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_card_get_path(card); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_CARD_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_CARD_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_card_free(card); @@ -1666,14 +1662,14 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_sink *sink = pa_idxset_get_by_index(core->sinks, idx); if (!(device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))) { - device = pa_dbusiface_device_new_sink(sink, OBJECT_PATH); + device = pa_dbusiface_device_new_sink(c, sink); pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device); } object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_SINK].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_SINK].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1685,7 +1681,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 * the D-Bus sink object wasn't created yet. Now that the * object is created, let's send the fallback sink change * signal. */ - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1698,7 +1694,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_SINK_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_SINK_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device); @@ -1710,14 +1706,14 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_source *source = pa_idxset_get_by_index(core->sources, idx); if (!(device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(idx)))) { - device = pa_dbusiface_device_new_source(source, OBJECT_PATH); + device = pa_dbusiface_device_new_source(c, source); pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device); } object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_SOURCE].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_SOURCE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1729,7 +1725,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 * point the D-Bus source object wasn't created yet. Now * that the object is created, let's send the fallback * source change signal. */ - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1742,7 +1738,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_SOURCE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_SOURCE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device); @@ -1752,13 +1748,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SINK_INPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { if (!(stream = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(idx)))) { - stream = pa_dbusiface_stream_new_playback(pa_idxset_get_by_index(core->sink_inputs, idx), OBJECT_PATH); + stream = pa_dbusiface_stream_new_playback(c, pa_idxset_get_by_index(core->sink_inputs, idx)); pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream); } object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1766,7 +1762,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream); @@ -1776,13 +1772,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { if (!(stream = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(idx)))) { - stream = pa_dbusiface_stream_new_record(pa_idxset_get_by_index(core->source_outputs, idx), OBJECT_PATH); + stream = pa_dbusiface_stream_new_record(c, pa_idxset_get_by_index(core->source_outputs, idx)); pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream); } object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_RECORD_STREAM].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_RECORD_STREAM].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1790,7 +1786,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_RECORD_STREAM_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_RECORD_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream); @@ -1800,13 +1796,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { if (!(sample = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(idx)))) { - sample = pa_dbusiface_sample_new(pa_idxset_get_by_index(core->scache, idx), OBJECT_PATH); + sample = pa_dbusiface_sample_new(c, pa_idxset_get_by_index(core->scache, idx)); pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), sample); } object_path = pa_dbusiface_sample_get_path(sample); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_SAMPLE].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_SAMPLE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1814,7 +1810,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_sample_get_path(sample); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_SAMPLE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_SAMPLE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_sample_free(sample); @@ -1824,13 +1820,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_MODULE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { if (!(module = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) { - module = pa_dbusiface_module_new(pa_idxset_get_by_index(core->modules, idx), OBJECT_PATH); + module = pa_dbusiface_module_new(c, pa_idxset_get_by_index(core->modules, idx)); pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module); } object_path = pa_dbusiface_module_get_path(module); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_MODULE].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_MODULE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1838,7 +1834,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_module_get_path(module); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_MODULE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_MODULE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_module_free(module); @@ -1848,13 +1844,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_CLIENT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { if (!(client = pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(idx)))) { - client = pa_dbusiface_client_new(pa_idxset_get_by_index(core->clients, idx), OBJECT_PATH); + client = pa_dbusiface_client_new(c, pa_idxset_get_by_index(core->clients, idx)); pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), client); } object_path = pa_dbusiface_client_get_path(client); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_CLIENT].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_CLIENT].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1862,7 +1858,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_client_get_path(client); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_CLIENT_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_CLIENT_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_client_free(client); @@ -1884,7 +1880,7 @@ static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_NEW_EXTENSION].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_EXTENSION].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1901,7 +1897,7 @@ static pa_hook_result_t extension_unregistered_cb(void *hook_data, void *call_da pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(OBJECT_PATH, PA_DBUSIFACE_CORE_INTERFACE, signals[SIGNAL_EXTENSION_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_EXTENSION_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1943,39 +1939,39 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { c->fallback_source = pa_namereg_get_default_source(core); c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED, PA_HOOK_NORMAL, extension_registered_cb, c); c->extension_unregistered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED, PA_HOOK_NORMAL, extension_unregistered_cb, c); - c->memstats = pa_dbusiface_memstats_new(core, OBJECT_PATH); + c->memstats = pa_dbusiface_memstats_new(c, core); for (card = pa_idxset_first(core->cards, &idx); card; card = pa_idxset_next(core->cards, &idx)) - pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(card, OBJECT_PATH)); + pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(c, card)); for (sink = pa_idxset_first(core->sinks, &idx); sink; sink = pa_idxset_next(core->sinks, &idx)) { - device = pa_dbusiface_device_new_sink(sink, OBJECT_PATH); + device = pa_dbusiface_device_new_sink(c, sink); pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device); } for (source = pa_idxset_first(core->sources, &idx); source; source = pa_idxset_next(core->sources, &idx)) { - device = pa_dbusiface_device_new_source(source, OBJECT_PATH); + device = pa_dbusiface_device_new_source(c, source); pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device); } for (sink_input = pa_idxset_first(core->sink_inputs, &idx); sink_input; sink_input = pa_idxset_next(core->sink_inputs, &idx)) - pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_playback(sink_input, OBJECT_PATH)); + pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_playback(c, sink_input)); for (source_output = pa_idxset_first(core->source_outputs, &idx); source_output; source_output = pa_idxset_next(core->source_outputs, &idx)) - pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_record(source_output, OBJECT_PATH)); + pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_record(c, source_output)); for (sample = pa_idxset_first(core->scache, &idx); sample; sample = pa_idxset_next(core->scache, &idx)) - pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), pa_dbusiface_sample_new(sample, OBJECT_PATH)); + pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), pa_dbusiface_sample_new(c, sample)); for (module = pa_idxset_first(core->modules, &idx); module; module = pa_idxset_next(core->modules, &idx)) - pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(module, OBJECT_PATH)); + pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(c, module)); for (client = pa_idxset_first(core->clients, &idx); client; client = pa_idxset_next(core->clients, &idx)) - pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(client, OBJECT_PATH)); + pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(c, client)); - pa_dbus_protocol_add_interface(c->dbus_protocol, OBJECT_PATH, &core_interface_info, c); + pa_dbus_protocol_add_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, &core_interface_info, c); return c; } @@ -2031,7 +2027,7 @@ static void free_client_cb(void *p, void *userdata) { void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_assert(c); - pa_dbus_protocol_remove_interface(c->dbus_protocol, OBJECT_PATH, core_interface_info.name); + pa_dbus_protocol_remove_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, core_interface_info.name); pa_subscription_free(c->subscription); pa_hashmap_free(c->cards, free_card_cb, NULL); -- cgit From 06232e2965ee02d62ca566fcbf5e805c571b574a Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 9 Aug 2009 09:04:15 +0300 Subject: dbus: Take advantage of the PA_HASHMAP_FOREACH macro. --- src/modules/dbus/iface-core.c | 64 ++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 40 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index e40cb979..685ba63b 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -542,7 +542,7 @@ static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *ms /* The caller frees the array, but not the strings. */ static const char **get_cards(pa_dbusiface_core *c, unsigned *n) { const char **cards; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_card *card; @@ -556,10 +556,8 @@ static const char **get_cards(pa_dbusiface_core *c, unsigned *n) { cards = pa_xnew(const char *, *n); - for (i = 0, card = pa_hashmap_iterate(c->cards, &state, NULL); card; ++i, card = pa_hashmap_iterate(c->cards, &state, NULL)) - cards[i] = pa_dbusiface_card_get_path(card); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(card, c->cards, state) + cards[i++] = pa_dbusiface_card_get_path(card); return cards; } @@ -583,7 +581,7 @@ static void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userd /* The caller frees the array, but not the strings. */ static const char **get_sinks(pa_dbusiface_core *c, unsigned *n) { const char **sinks; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_device *sink; @@ -597,10 +595,8 @@ static const char **get_sinks(pa_dbusiface_core *c, unsigned *n) { sinks = pa_xnew(const char *, *n); - for (i = 0, sink = pa_hashmap_iterate(c->sinks_by_index, &state, NULL); sink; ++i, sink = pa_hashmap_iterate(c->sinks_by_index, &state, NULL)) - sinks[i] = pa_dbusiface_device_get_path(sink); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(sink, c->sinks_by_index, state) + sinks[i++] = pa_dbusiface_device_get_path(sink); return sinks; } @@ -671,7 +667,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, voi /* The caller frees the array, but not the strings. */ static const char **get_sources(pa_dbusiface_core *c, unsigned *n) { const char **sources; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_device *source; @@ -685,10 +681,8 @@ static const char **get_sources(pa_dbusiface_core *c, unsigned *n) { sources = pa_xnew(const char *, *n); - for (i = 0, source = pa_hashmap_iterate(c->sources_by_index, &state, NULL); source; ++i, source = pa_hashmap_iterate(c->sources_by_index, &state, NULL)) - sources[i] = pa_dbusiface_device_get_path(source); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(source, c->sources_by_index, state) + sources[i++] = pa_dbusiface_device_get_path(source); return sources; } @@ -759,7 +753,7 @@ static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, v /* The caller frees the array, but not the strings. */ static const char **get_playback_streams(pa_dbusiface_core *c, unsigned *n) { const char **streams; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_stream *stream; @@ -773,10 +767,8 @@ static const char **get_playback_streams(pa_dbusiface_core *c, unsigned *n) { streams = pa_xnew(const char *, *n); - for (i = 0, stream = pa_hashmap_iterate(c->playback_streams, &state, NULL); stream; ++i, stream = pa_hashmap_iterate(c->playback_streams, &state, NULL)) - streams[i] = pa_dbusiface_stream_get_path(stream); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(stream, c->playback_streams, state) + streams[i++] = pa_dbusiface_stream_get_path(stream); return streams; } @@ -800,7 +792,7 @@ static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, /* The caller frees the array, but not the strings. */ static const char **get_record_streams(pa_dbusiface_core *c, unsigned *n) { const char **streams; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_stream *stream; @@ -814,10 +806,8 @@ static const char **get_record_streams(pa_dbusiface_core *c, unsigned *n) { streams = pa_xnew(const char *, *n); - for (i = 0, stream = pa_hashmap_iterate(c->record_streams, &state, NULL); stream; ++i, stream = pa_hashmap_iterate(c->record_streams, &state, NULL)) - streams[i] = pa_dbusiface_stream_get_path(stream); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(stream, c->record_streams, state) + streams[i++] = pa_dbusiface_stream_get_path(stream); return streams; } @@ -841,7 +831,7 @@ static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, vo /* The caller frees the array, but not the strings. */ static const char **get_samples(pa_dbusiface_core *c, unsigned *n) { const char **samples; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_sample *sample; @@ -855,10 +845,8 @@ static const char **get_samples(pa_dbusiface_core *c, unsigned *n) { samples = pa_xnew(const char *, *n); - for (i = 0, sample = pa_hashmap_iterate(c->samples, &state, NULL); sample; ++i, sample = pa_hashmap_iterate(c->samples, &state, NULL)) - samples[i] = pa_dbusiface_sample_get_path(sample); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(sample, c->samples, state) + samples[i++] = pa_dbusiface_sample_get_path(sample); return samples; } @@ -882,7 +870,7 @@ static void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *use /* The caller frees the array, but not the strings. */ static const char **get_modules(pa_dbusiface_core *c, unsigned *n) { const char **modules; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_module *module; @@ -896,10 +884,8 @@ static const char **get_modules(pa_dbusiface_core *c, unsigned *n) { modules = pa_xnew(const char *, *n); - for (i = 0, module = pa_hashmap_iterate(c->modules, &state, NULL); module; ++i, module = pa_hashmap_iterate(c->modules, &state, NULL)) - modules[i] = pa_dbusiface_module_get_path(module); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(module, c->modules, state) + modules[i++] = pa_dbusiface_module_get_path(module); return modules; } @@ -923,7 +909,7 @@ static void handle_get_modules(DBusConnection *conn, DBusMessage *msg, void *use /* The caller frees the array, but not the strings. */ static const char **get_clients(pa_dbusiface_core *c, unsigned *n) { const char **clients; - unsigned i; + unsigned i = 0; void *state = NULL; pa_dbusiface_client *client; @@ -937,10 +923,8 @@ static const char **get_clients(pa_dbusiface_core *c, unsigned *n) { clients = pa_xnew(const char *, *n); - for (i = 0, client = pa_hashmap_iterate(c->clients, &state, NULL); client; ++i, client = pa_hashmap_iterate(c->clients, &state, NULL)) - clients[i] = pa_dbusiface_client_get_path(client); - - pa_assert(i == *n); + PA_HASHMAP_FOREACH(client, c->clients, state) + clients[i++] = pa_dbusiface_client_get_path(client); return clients; } -- cgit From 0b6662023bfb121b0e553ce00b4229705c8e7aef Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 9 Aug 2009 09:06:21 +0300 Subject: dbusiface-core: Generate more informative error messages. --- src/modules/dbus/iface-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 685ba63b..be07648c 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -655,7 +655,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, voi return; if (!(fallback_sink = pa_hashmap_get(c->sinks_by_path, object_path))) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sink."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", object_path); return; } @@ -741,7 +741,7 @@ static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, v return; if (!(fallback_source = pa_hashmap_get(c->sources_by_path, object_path))) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such source."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", object_path); return; } @@ -1154,7 +1154,7 @@ static void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void } if (!(sink = pa_namereg_get(c->core, sink_name, PA_NAMEREG_SINK))) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sink."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", sink_name); return; } @@ -1186,7 +1186,7 @@ static void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, vo } if (!(source = pa_namereg_get(c->core, source_name, PA_NAMEREG_SOURCE))) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such source."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", source_name); return; } -- cgit From 5ece8e8833ff40a4c535fc7d6705377fcf7fd0fd Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 9 Aug 2009 09:10:05 +0300 Subject: dbusiface-core: Add functions for getting various object paths. --- src/modules/dbus/iface-core.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index be07648c..e8ea50ba 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -2033,3 +2033,24 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_xfree(c); } + +const char *pa_dbusiface_core_get_sink_path(pa_dbusiface_core *c, const pa_sink *sink) { + pa_assert(c); + pa_assert(sink); + + return pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(sink->index))); +} + +const char *pa_dbusiface_core_get_source_path(pa_dbusiface_core *c, const pa_source *source) { + pa_assert(c); + pa_assert(source); + + return pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(source->index))); +} + +const char *pa_dbusiface_core_get_module_path(pa_dbusiface_core *c, const pa_module *module) { + pa_assert(c); + pa_assert(module); + + return pa_dbusiface_module_get_path(pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(module->index))); +} -- cgit From 1e65d8d35b23d3c76a30155c42bec282257579e5 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sat, 15 Aug 2009 06:11:38 +0300 Subject: dbusiface-core: New function: pa_dbusiface_core_get_card_path(). --- src/modules/dbus/iface-core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index e8ea50ba..81e709f5 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -2034,6 +2034,13 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_xfree(c); } +const char *pa_dbusiface_core_get_card_path(pa_dbusiface_core *c, const pa_card *card) { + pa_assert(c); + pa_assert(card); + + return pa_dbusiface_card_get_path(pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(card->index))); +} + const char *pa_dbusiface_core_get_sink_path(pa_dbusiface_core *c, const pa_sink *sink) { pa_assert(c); pa_assert(sink); -- cgit From f663d13acd306feafe2526c6a9258f14fd5d2ffc Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sat, 15 Aug 2009 16:54:11 +0300 Subject: dbusiface-core: Two new functions: pa_dbusiface_core_get_playback/record_stream_path(). --- src/modules/dbus/iface-core.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 81e709f5..2b5cf0b9 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -2055,6 +2055,20 @@ const char *pa_dbusiface_core_get_source_path(pa_dbusiface_core *c, const pa_sou return pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(source->index))); } +const char *pa_dbusiface_core_get_playback_stream_path(pa_dbusiface_core *c, const pa_sink_input *sink_input) { + pa_assert(c); + pa_assert(sink_input); + + return pa_dbusiface_stream_get_path(pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(sink_input->index))); +} + +const char *pa_dbusiface_core_get_record_stream_path(pa_dbusiface_core *c, const pa_source_output *source_output) { + pa_assert(c); + pa_assert(source_output); + + return pa_dbusiface_stream_get_path(pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(source_output->index))); +} + const char *pa_dbusiface_core_get_module_path(pa_dbusiface_core *c, const pa_module *module) { pa_assert(c); pa_assert(module); -- cgit From a10e8360d72626635de1242cfc2c77207f13d56f Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Mon, 17 Aug 2009 16:42:06 +0300 Subject: dbusiface-core: New function: pa_dbusiface_core_get_client_path(). --- src/modules/dbus/iface-core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 2b5cf0b9..ec87158f 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -2075,3 +2075,10 @@ const char *pa_dbusiface_core_get_module_path(pa_dbusiface_core *c, const pa_mod return pa_dbusiface_module_get_path(pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(module->index))); } + +const char *pa_dbusiface_core_get_client_path(pa_dbusiface_core *c, const pa_client *client) { + pa_assert(c); + pa_assert(client); + + return pa_dbusiface_client_get_path(pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(client->index))); +} -- cgit From efec274b6dcf239f580713f889957c370ac7ffc7 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Mon, 17 Aug 2009 16:42:58 +0300 Subject: dbusiface-core: Two new functions: pa_dbusiface_core_get_sink/source(). --- src/modules/dbus/iface-core.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index ec87158f..86a8fc7b 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -2082,3 +2082,31 @@ const char *pa_dbusiface_core_get_client_path(pa_dbusiface_core *c, const pa_cli return pa_dbusiface_client_get_path(pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(client->index))); } + +pa_sink *pa_dbusiface_core_get_sink(pa_dbusiface_core *c, const char *object_path) { + pa_dbusiface_device *device = NULL; + + pa_assert(c); + pa_assert(object_path); + + device = pa_hashmap_get(c->sinks_by_path, object_path); + + if (device) + return pa_dbusiface_device_get_sink(device); + else + return NULL; +} + +pa_source *pa_dbusiface_core_get_source(pa_dbusiface_core *c, const char *object_path) { + pa_dbusiface_device *device = NULL; + + pa_assert(c); + pa_assert(object_path); + + device = pa_hashmap_get(c->sources_by_path, object_path); + + if (device) + return pa_dbusiface_device_get_source(device); + else + return NULL; +} -- cgit From 8e6664f499ff3431ea51c99baf366ef11c5301a5 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Wed, 19 Aug 2009 09:09:40 +0300 Subject: dbusiface-core: Split some overly long lines. --- src/modules/dbus/iface-core.c | 160 +++++++++++++++++++++++++++++++----------- 1 file changed, 118 insertions(+), 42 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 86a8fc7b..946fdcc2 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -450,7 +450,8 @@ static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, } if (n_channels > PA_CHANNELS_MAX) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too many channels: %u. The maximum number of channels is %u.", n_channels, PA_CHANNELS_MAX); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Too many channels: %u. The maximum number of channels is %u.", n_channels, PA_CHANNELS_MAX); return; } @@ -627,7 +628,8 @@ static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, voi pa_assert(c); if (!c->fallback_sink) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sinks, and therefore no fallback sink either."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, + "There are no sinks, and therefore no fallback sink either."); return; } @@ -647,7 +649,8 @@ static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, voi pa_assert(c); if (!c->fallback_sink) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sinks, and therefore no fallback sink either."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, + "There are no sinks, and therefore no fallback sink either."); return; } @@ -713,7 +716,8 @@ static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, v pa_assert(c); if (!c->fallback_source) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sources, and therefore no fallback source either."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, + "There are no sources, and therefore no fallback source either."); return; } @@ -733,7 +737,8 @@ static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, v pa_assert(c); if (!c->fallback_source) { - pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, "There are no sources, and therefore no fallback source either."); + pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NO_SUCH_PROPERTY, + "There are no sources, and therefore no fallback source either."); return; } @@ -1037,9 +1042,14 @@ static void handle_get_all(DBusConnection *conn, DBusMessage *msg, void *userdat default_sample_rate = c->core->default_sample_spec.rate; cards = get_cards(c, &n_cards); sinks = get_sinks(c, &n_sinks); - fallback_sink = c->fallback_sink ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index))) : NULL; + fallback_sink = c->fallback_sink + ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(c->fallback_sink->index))) + : NULL; sources = get_sources(c, &n_sources); - fallback_source = c->fallback_source ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(c->fallback_source->index))) : NULL; + fallback_source = c->fallback_source + ? pa_dbusiface_device_get_path(pa_hashmap_get(c->sources_by_index, + PA_UINT32_TO_PTR(c->fallback_source->index))) + : NULL; playback_streams = get_playback_streams(c, &n_playback_streams); record_streams = get_record_streams(c, &n_record_streams); samples = get_samples(c, &n_samples); @@ -1299,7 +1309,8 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u } if (n_channels > PA_CHANNELS_MAX) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too many channels."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Too many channels: %u. The maximum is %u.", n_channels, PA_CHANNELS_MAX); goto finish; } @@ -1311,7 +1322,8 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u } if (n_volume_entries != 0 && n_volume_entries != n_channels) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "The channels and default_volume arguments have different number of elements."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "The channels and default_volume arguments have different number of elements."); goto finish; } @@ -1337,7 +1349,8 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u ss.channels = n_channels; if (!pa_frame_aligned(data_length, &ss)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "The sample length in bytes doesn't align with the sample format and channels."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "The sample length in bytes doesn't align with the sample format and channels."); goto finish; } @@ -1431,15 +1444,19 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use arg_type = dbus_message_iter_get_arg_type(&msg_iter); if (arg_type != DBUS_TYPE_ARRAY) { if (arg_type == DBUS_TYPE_INVALID) - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments. A dictionary from strings to strings was expected."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Too few arguments. A dictionary from strings to strings was expected."); else - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong argument type: '%c'. An dictionary from strings to strings was expected.", (char) arg_type); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Wrong argument type: '%c'. An dictionary from strings to strings was expected.", + (char) arg_type); return; } arg_type = dbus_message_iter_get_element_type(&msg_iter); if (arg_type != DBUS_TYPE_DICT_ENTRY) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong array element type: '%c'. A dict entry (string to string) was expected.", (char) arg_type); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Wrong array element type: '%c'. A dict entry (string to string) was expected.", (char) arg_type); return; } @@ -1455,7 +1472,8 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use arg_type = dbus_message_iter_get_arg_type(&dict_entry_iter); if (arg_type != DBUS_TYPE_STRING) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict key type: '%c'. A string was expected.", (char) arg_type); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Wrong dict key type: '%c'. A string was expected.", (char) arg_type); goto finish; } @@ -1472,7 +1490,8 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use if (arg_type == DBUS_TYPE_INVALID) pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Dict value missing."); else - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Wrong dict value type: '%c'. A string was expected.", (char) arg_type); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Wrong dict value type: '%c'. A string was expected.", (char) arg_type); goto finish; } @@ -1532,7 +1551,10 @@ static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, voi dbus_error_init(&error); - if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &signal, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, DBUS_TYPE_INVALID)) { + if (!dbus_message_get_args(msg, &error, + DBUS_TYPE_STRING, &signal, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, + DBUS_TYPE_INVALID)) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); dbus_error_free(&error); goto finish; @@ -1591,10 +1613,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (c->fallback_sink != new_fallback_sink) { c->fallback_sink = new_fallback_sink; - if (new_fallback_sink && (device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { + if (new_fallback_sink + && (device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); @@ -1605,10 +1630,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if (c->fallback_source != new_fallback_source) { c->fallback_source = new_fallback_source; - if (new_fallback_source && (device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { + if (new_fallback_source + && (device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); @@ -1626,7 +1654,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_card_get_path(card); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_CARD].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_CARD].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1634,7 +1664,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_card_get_path(card); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_CARD_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_CARD_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_card_free(card); @@ -1653,7 +1685,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_SINK].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_SINK].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1665,7 +1699,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 * the D-Bus sink object wasn't created yet. Now that the * object is created, let's send the fallback sink change * signal. */ - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SINK_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1678,7 +1714,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_SINK_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_SINK_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device); @@ -1697,7 +1735,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_SOURCE].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_SOURCE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1709,7 +1749,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 * point the D-Bus source object wasn't created yet. Now * that the object is created, let's send the fallback * source change signal. */ - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SOURCE_UPDATED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1722,7 +1764,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_device_get_path(device); pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path)); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_SOURCE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_SOURCE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_device_free(device); @@ -1738,7 +1782,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_PLAYBACK_STREAM].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1746,7 +1792,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream); @@ -1762,7 +1810,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_RECORD_STREAM].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_RECORD_STREAM].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1770,7 +1820,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_stream_get_path(stream); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_RECORD_STREAM_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_RECORD_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_stream_free(stream); @@ -1786,7 +1838,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_sample_get_path(sample); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_SAMPLE].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_SAMPLE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1794,7 +1848,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_sample_get_path(sample); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_SAMPLE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_SAMPLE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_sample_free(sample); @@ -1810,7 +1866,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_module_get_path(module); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_MODULE].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_MODULE].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1818,7 +1876,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_module_get_path(module); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_MODULE_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_MODULE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_module_free(module); @@ -1834,7 +1894,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_client_get_path(client); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_CLIENT].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_CLIENT].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { @@ -1842,7 +1904,9 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 object_path = pa_dbusiface_client_get_path(client); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_CLIENT_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_CLIENT_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); pa_dbusiface_client_free(client); @@ -1864,7 +1928,9 @@ static pa_hook_result_t extension_registered_cb(void *hook_data, void *call_data pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_NEW_EXTENSION].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_NEW_EXTENSION].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1881,7 +1947,9 @@ static pa_hook_result_t extension_unregistered_cb(void *hook_data, void *call_da pa_assert(c); pa_assert(ext_name); - pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_EXTENSION_REMOVED].name))); + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_EXTENSION_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_STRING, &ext_name, DBUS_TYPE_INVALID)); pa_dbus_protocol_send_signal(c->dbus_protocol, signal); @@ -1921,8 +1989,16 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { c->clients = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); c->fallback_sink = pa_namereg_get_default_sink(core); c->fallback_source = pa_namereg_get_default_source(core); - c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED, PA_HOOK_NORMAL, extension_registered_cb, c); - c->extension_unregistered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED, PA_HOOK_NORMAL, extension_unregistered_cb, c); + c->extension_registered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, + PA_DBUS_PROTOCOL_HOOK_EXTENSION_REGISTERED, + PA_HOOK_NORMAL, + extension_registered_cb, + c); + c->extension_unregistered_slot = pa_dbus_protocol_hook_connect(c->dbus_protocol, + PA_DBUS_PROTOCOL_HOOK_EXTENSION_UNREGISTERED, + PA_HOOK_NORMAL, + extension_unregistered_cb, + c); c->memstats = pa_dbusiface_memstats_new(c, core); for (card = pa_idxset_first(core->cards, &idx); card; card = pa_idxset_next(core->cards, &idx)) -- cgit From 636dbc31f9f7acd76402ea01121f327d21315177 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Wed, 19 Aug 2009 09:10:38 +0300 Subject: dbusiface-core: Use the PA_IDXSET_FOREACH macro. --- src/modules/dbus/iface-core.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 946fdcc2..e0aedbec 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -2001,34 +2001,34 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { c); c->memstats = pa_dbusiface_memstats_new(c, core); - for (card = pa_idxset_first(core->cards, &idx); card; card = pa_idxset_next(core->cards, &idx)) + PA_IDXSET_FOREACH(card, core->cards, idx) pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(c, card)); - for (sink = pa_idxset_first(core->sinks, &idx); sink; sink = pa_idxset_next(core->sinks, &idx)) { + PA_IDXSET_FOREACH(sink, core->sinks, idx) { device = pa_dbusiface_device_new_sink(c, sink); pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device); } - for (source = pa_idxset_first(core->sources, &idx); source; source = pa_idxset_next(core->sources, &idx)) { + PA_IDXSET_FOREACH(source, core->sources, idx) { device = pa_dbusiface_device_new_source(c, source); pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device); } - for (sink_input = pa_idxset_first(core->sink_inputs, &idx); sink_input; sink_input = pa_idxset_next(core->sink_inputs, &idx)) + PA_IDXSET_FOREACH(sink_input, core->sink_inputs, idx) pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_playback(c, sink_input)); - for (source_output = pa_idxset_first(core->source_outputs, &idx); source_output; source_output = pa_idxset_next(core->source_outputs, &idx)) + PA_IDXSET_FOREACH(source_output, core->source_outputs, idx) pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), pa_dbusiface_stream_new_record(c, source_output)); - for (sample = pa_idxset_first(core->scache, &idx); sample; sample = pa_idxset_next(core->scache, &idx)) + PA_IDXSET_FOREACH(sample, core->scache, idx) pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), pa_dbusiface_sample_new(c, sample)); - for (module = pa_idxset_first(core->modules, &idx); module; module = pa_idxset_next(core->modules, &idx)) + PA_IDXSET_FOREACH(module, core->modules, idx) pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(c, module)); - for (client = pa_idxset_first(core->clients, &idx); client; client = pa_idxset_next(core->clients, &idx)) + PA_IDXSET_FOREACH(client, core->clients, idx) pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(c, client)); pa_dbus_protocol_add_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, &core_interface_info, c); -- cgit From 3de210b67120debc680d74e93118a80d360fe1e1 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Wed, 19 Aug 2009 09:13:59 +0300 Subject: dbusiface-core: Assert that _add/remove_interface calls succeed. --- src/modules/dbus/iface-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index e0aedbec..a0694d6f 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -2031,7 +2031,7 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { PA_IDXSET_FOREACH(client, core->clients, idx) pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(c, client)); - pa_dbus_protocol_add_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, &core_interface_info, c); + pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, &core_interface_info, c) >= 0); return c; } @@ -2087,7 +2087,7 @@ static void free_client_cb(void *p, void *userdata) { void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_assert(c); - pa_dbus_protocol_remove_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, core_interface_info.name); + pa_assert_se(pa_dbus_protocol_remove_interface(c->dbus_protocol, PA_DBUS_CORE_OBJECT_PATH, core_interface_info.name) >= 0); pa_subscription_free(c->subscription); pa_hashmap_free(c->cards, free_card_cb, NULL); -- cgit From 3025645b0b58f476f6404f2aed3b61a633794d10 Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Mon, 24 Aug 2009 14:27:14 +0300 Subject: dbusiface-module: Implement the Module D-Bus interface. --- src/modules/dbus/iface-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index a0694d6f..9e8f775e 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -1509,7 +1509,7 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use goto finish; } - dbus_module = pa_dbusiface_module_new(c, module); + dbus_module = pa_dbusiface_module_new(module); pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(module->index), dbus_module); object_path = pa_dbusiface_module_get_path(dbus_module); @@ -1860,7 +1860,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_MODULE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { if (!(module = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) { - module = pa_dbusiface_module_new(c, pa_idxset_get_by_index(core->modules, idx)); + module = pa_dbusiface_module_new(pa_idxset_get_by_index(core->modules, idx)); pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module); } @@ -2026,7 +2026,7 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), pa_dbusiface_sample_new(c, sample)); PA_IDXSET_FOREACH(module, core->modules, idx) - pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(c, module)); + pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), pa_dbusiface_module_new(module)); PA_IDXSET_FOREACH(client, core->clients, idx) pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), pa_dbusiface_client_new(c, client)); -- cgit From edf80104e32830a3d4ec58f88f9a092c32203d8a Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Wed, 26 Aug 2009 14:17:35 +0300 Subject: dbus: Make sure that subscription callbacks don't try to access removed objects. --- src/modules/dbus/iface-core.c | 202 +++++++++++++++++++++++++++--------------- 1 file changed, 131 insertions(+), 71 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 9e8f775e..c54a3b7a 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -1592,12 +1592,12 @@ static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage * static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { pa_dbusiface_core *c = userdata; - pa_dbusiface_card *card = NULL; - pa_dbusiface_device *device = NULL; - pa_dbusiface_stream *stream = NULL; - pa_dbusiface_sample *sample = NULL; - pa_dbusiface_module *module = NULL; - pa_dbusiface_client *client = NULL; + pa_dbusiface_card *card_iface = NULL; + pa_dbusiface_device *device_iface = NULL; + pa_dbusiface_stream *stream_iface = NULL; + pa_dbusiface_sample *sample_iface = NULL; + pa_dbusiface_module *module_iface = NULL; + pa_dbusiface_client *client_iface = NULL; DBusMessage *signal = NULL; const char *object_path = NULL; pa_sink *new_fallback_sink = NULL; @@ -1611,11 +1611,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 new_fallback_source = pa_namereg_get_default_source(core); if (c->fallback_sink != new_fallback_sink) { - c->fallback_sink = new_fallback_sink; + if (c->fallback_sink) + pa_sink_unref(c->fallback_sink); + c->fallback_sink = new_fallback_sink ? pa_sink_ref(new_fallback_sink) : NULL; if (new_fallback_sink - && (device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { - object_path = pa_dbusiface_device_get_path(device); + && (device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(new_fallback_sink->index)))) { + object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1628,11 +1630,13 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 } if (c->fallback_source != new_fallback_source) { - c->fallback_source = new_fallback_source; + if (c->fallback_source) + pa_source_unref(c->fallback_source); + c->fallback_source = new_fallback_source ? pa_source_ref(new_fallback_source) : NULL; if (new_fallback_source - && (device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { - object_path = pa_dbusiface_device_get_path(device); + && (device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(new_fallback_source->index)))) { + object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1647,12 +1651,17 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 case PA_SUBSCRIPTION_EVENT_CARD: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - if (!(card = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(idx)))) { - card = pa_dbusiface_card_new(c, pa_idxset_get_by_index(core->cards, idx)); - pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), card); + if (!(card_iface = pa_hashmap_get(c->cards, PA_UINT32_TO_PTR(idx)))) { + pa_card *card = NULL; + + if (!(card = pa_idxset_get_by_index(core->cards, idx))) + return; /* The card was removed immediately after creation. */ + + card_iface = pa_dbusiface_card_new(c, card); + pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), card_iface); } - object_path = pa_dbusiface_card_get_path(card); + object_path = pa_dbusiface_card_get_path(card_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1660,30 +1669,34 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((card = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(idx)))); + if (!(card_iface = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(idx)))) + return; - object_path = pa_dbusiface_card_get_path(card); + object_path = pa_dbusiface_card_get_path(card_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_CARD_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_card_free(card); + pa_dbusiface_card_free(card_iface); } break; case PA_SUBSCRIPTION_EVENT_SINK: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - pa_sink *sink = pa_idxset_get_by_index(core->sinks, idx); + pa_sink *sink = NULL; - if (!(device = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))) { - device = pa_dbusiface_device_new_sink(c, sink); - pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device); - pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device); + if (!(sink = pa_idxset_get_by_index(core->sinks, idx))) + return; /* The sink was removed immediately after creation. */ + + if (!(device_iface = pa_hashmap_get(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))) { + device_iface = pa_dbusiface_device_new_sink(c, sink); + pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device_iface); + pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device_iface), device_iface); } - object_path = pa_dbusiface_device_get_path(device); + object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1710,8 +1723,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 } } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((device = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))); - object_path = pa_dbusiface_device_get_path(device); + if (!(device_iface = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(idx)))) + return; + + object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path)); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, @@ -1719,7 +1734,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 signals[SIGNAL_SINK_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_device_free(device); + pa_dbusiface_device_free(device_iface); } break; @@ -1727,13 +1742,16 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { pa_source *source = pa_idxset_get_by_index(core->sources, idx); - if (!(device = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(idx)))) { - device = pa_dbusiface_device_new_source(c, source); - pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device); - pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device); + if (!(source = pa_idxset_get_by_index(core->sources, idx))) + return; /* The source was removed immediately after creation. */ + + if (!(device_iface = pa_hashmap_get(c->sources_by_index, PA_UINT32_TO_PTR(idx)))) { + device_iface = pa_dbusiface_device_new_source(c, source); + pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device_iface); + pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device_iface), device_iface); } - object_path = pa_dbusiface_device_get_path(device); + object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1760,8 +1778,10 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 } } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((device = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(idx)))); - object_path = pa_dbusiface_device_get_path(device); + if (!(device_iface = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(idx)))) + return; + + object_path = pa_dbusiface_device_get_path(device_iface); pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path)); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, @@ -1769,18 +1789,23 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 signals[SIGNAL_SOURCE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_device_free(device); + pa_dbusiface_device_free(device_iface); } break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - if (!(stream = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(idx)))) { - stream = pa_dbusiface_stream_new_playback(c, pa_idxset_get_by_index(core->sink_inputs, idx)); - pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream); + pa_sink_input *sink_input = NULL; + + if (!(sink_input = pa_idxset_get_by_index(core->sink_inputs, idx))) + return; /* The sink input was removed immediately after creation. */ + + if (!(stream_iface = pa_hashmap_get(c->playback_streams, PA_UINT32_TO_PTR(idx)))) { + stream_iface = pa_dbusiface_stream_new_playback(c, sink_input); + pa_hashmap_put(c->playback_streams, PA_UINT32_TO_PTR(idx), stream_iface); } - object_path = pa_dbusiface_stream_get_path(stream); + object_path = pa_dbusiface_stream_get_path(stream_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1788,27 +1813,33 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((stream = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx)))); + if (!(stream_iface = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx)))) + return; - object_path = pa_dbusiface_stream_get_path(stream); + object_path = pa_dbusiface_stream_get_path(stream_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_PLAYBACK_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_stream_free(stream); + pa_dbusiface_stream_free(stream_iface); } break; case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - if (!(stream = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(idx)))) { - stream = pa_dbusiface_stream_new_record(c, pa_idxset_get_by_index(core->source_outputs, idx)); - pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream); + pa_source_output *source_output = NULL; + + if (!(source_output = pa_idxset_get_by_index(core->source_outputs, idx))) + return; /* The source output was removed immediately after creation. */ + + if (!(stream_iface = pa_hashmap_get(c->record_streams, PA_UINT32_TO_PTR(idx)))) { + stream_iface = pa_dbusiface_stream_new_record(c, source_output); + pa_hashmap_put(c->record_streams, PA_UINT32_TO_PTR(idx), stream_iface); } - object_path = pa_dbusiface_stream_get_path(stream); + object_path = pa_dbusiface_stream_get_path(stream_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1816,27 +1847,33 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((stream = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx)))); + if (!(stream_iface = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx)))) + return; - object_path = pa_dbusiface_stream_get_path(stream); + object_path = pa_dbusiface_stream_get_path(stream_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_RECORD_STREAM_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_stream_free(stream); + pa_dbusiface_stream_free(stream_iface); } break; case PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - if (!(sample = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(idx)))) { - sample = pa_dbusiface_sample_new(c, pa_idxset_get_by_index(core->scache, idx)); - pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), sample); + pa_scache_entry *sample = NULL; + + if (!(sample = pa_idxset_get_by_index(core->scache, idx))) + return; /* The sample was removed immediately after creation. */ + + if (!(sample_iface = pa_hashmap_get(c->samples, PA_UINT32_TO_PTR(idx)))) { + sample_iface = pa_dbusiface_sample_new(c, sample); + pa_hashmap_put(c->samples, PA_UINT32_TO_PTR(idx), sample_iface); } - object_path = pa_dbusiface_sample_get_path(sample); + object_path = pa_dbusiface_sample_get_path(sample_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1844,27 +1881,33 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((sample = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx)))); + if (!(sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx)))) + return; - object_path = pa_dbusiface_sample_get_path(sample); + object_path = pa_dbusiface_sample_get_path(sample_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_SAMPLE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_sample_free(sample); + pa_dbusiface_sample_free(sample_iface); } break; case PA_SUBSCRIPTION_EVENT_MODULE: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - if (!(module = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) { - module = pa_dbusiface_module_new(pa_idxset_get_by_index(core->modules, idx)); - pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module); + pa_module *module = NULL; + + if (!(module = pa_idxset_get_by_index(core->modules, idx))) + return; /* The module was removed immediately after creation. */ + + if (!(module_iface = pa_hashmap_get(c->modules, PA_UINT32_TO_PTR(idx)))) { + module_iface = pa_dbusiface_module_new(module); + pa_hashmap_put(c->modules, PA_UINT32_TO_PTR(idx), module_iface); } - object_path = pa_dbusiface_module_get_path(module); + object_path = pa_dbusiface_module_get_path(module_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1872,27 +1915,33 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((module = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx)))); + if (!(module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx)))) + return; - object_path = pa_dbusiface_module_get_path(module); + object_path = pa_dbusiface_module_get_path(module_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_MODULE_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_module_free(module); + pa_dbusiface_module_free(module_iface); } break; case PA_SUBSCRIPTION_EVENT_CLIENT: if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { - if (!(client = pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(idx)))) { - client = pa_dbusiface_client_new(c, pa_idxset_get_by_index(core->clients, idx)); - pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), client); + pa_client *client = NULL; + + if (!(client = pa_idxset_get_by_index(core->clients, idx))) + return; /* The client was removed immediately after creation. */ + + if (!(client_iface = pa_hashmap_get(c->clients, PA_UINT32_TO_PTR(idx)))) { + client_iface = pa_dbusiface_client_new(c, client); + pa_hashmap_put(c->clients, PA_UINT32_TO_PTR(idx), client_iface); } - object_path = pa_dbusiface_client_get_path(client); + object_path = pa_dbusiface_client_get_path(client_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, @@ -1900,16 +1949,17 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - pa_assert_se((client = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(idx)))); + if (!(client_iface = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(idx)))) + return; - object_path = pa_dbusiface_client_get_path(client); + object_path = pa_dbusiface_client_get_path(client_iface); pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, PA_DBUS_CORE_INTERFACE, signals[SIGNAL_CLIENT_REMOVED].name))); pa_assert_se(dbus_message_append_args(signal, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID)); - pa_dbusiface_client_free(client); + pa_dbusiface_client_free(client_iface); } break; } @@ -2001,6 +2051,11 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) { c); c->memstats = pa_dbusiface_memstats_new(c, core); + if (c->fallback_sink) + pa_sink_ref(c->fallback_sink); + if (c->fallback_source) + pa_source_ref(c->fallback_source); + PA_IDXSET_FOREACH(card, core->cards, idx) pa_hashmap_put(c->cards, PA_UINT32_TO_PTR(idx), pa_dbusiface_card_new(c, card)); @@ -2104,6 +2159,11 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) { pa_hook_slot_free(c->extension_unregistered_slot); pa_dbusiface_memstats_free(c->memstats); + if (c->fallback_sink) + pa_sink_unref(c->fallback_sink); + if (c->fallback_source) + pa_source_unref(c->fallback_source); + pa_dbus_protocol_unref(c->dbus_protocol); pa_core_unref(c->core); -- cgit From 0e096632c53b746b9f4b4c0249d9e5a18c1c543d Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Sun, 30 Aug 2009 19:52:22 +0300 Subject: dbus: Do message argument type checking early, centrally. --- src/modules/dbus/iface-core.c | 247 +++++++++++++++--------------------------- 1 file changed, 88 insertions(+), 159 deletions(-) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index c54a3b7a..0507ac9c 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -57,18 +57,18 @@ static void handle_get_is_local(DBusConnection *conn, DBusMessage *msg, void *us static void handle_get_username(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_hostname(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); static void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); static void handle_get_cards(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_sinks(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); static void handle_get_sources(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata); static void handle_get_playback_streams(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_record_streams(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_samples(DBusConnection *conn, DBusMessage *msg, void *userdata); @@ -428,30 +428,32 @@ static void handle_get_default_channels(DBusConnection *conn, DBusMessage *msg, pa_xfree(default_channels); } -static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, void *userdata) { +static void handle_set_default_channels(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { pa_dbusiface_core *c = userdata; + DBusMessageIter array_iter; pa_channel_map new_channel_map; - dbus_uint32_t *default_channels; - unsigned n_channels; + const dbus_uint32_t *default_channels; + int n_channels; unsigned i; pa_assert(conn); pa_assert(msg); + pa_assert(iter); pa_assert(c); pa_channel_map_init(&new_channel_map); - if (pa_dbus_get_fixed_array_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &default_channels, &n_channels) < 0) - return; + dbus_message_iter_recurse(iter, &array_iter); + dbus_message_iter_get_fixed_array(&array_iter, &default_channels, &n_channels); if (n_channels <= 0) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel array."); return; } - if (n_channels > PA_CHANNELS_MAX) { + if (n_channels > (int) PA_CHANNELS_MAX) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "Too many channels: %u. The maximum number of channels is %u.", n_channels, PA_CHANNELS_MAX); + "Too many channels: %i. The maximum number of channels is %u.", n_channels, PA_CHANNELS_MAX); return; } @@ -485,16 +487,16 @@ static void handle_get_default_sample_format(DBusConnection *conn, DBusMessage * pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_format); } -static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { +static void handle_set_default_sample_format(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { pa_dbusiface_core *c = userdata; dbus_uint32_t default_sample_format; pa_assert(conn); pa_assert(msg); + pa_assert(iter); pa_assert(c); - if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &default_sample_format) < 0) - return; + dbus_message_iter_get_basic(iter, &default_sample_format); if (default_sample_format >= PA_SAMPLE_MAX) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); @@ -519,16 +521,16 @@ static void handle_get_default_sample_rate(DBusConnection *conn, DBusMessage *ms pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_UINT32, &default_sample_rate); } -static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { +static void handle_set_default_sample_rate(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { pa_dbusiface_core *c = userdata; dbus_uint32_t default_sample_rate; pa_assert(conn); pa_assert(msg); + pa_assert(iter); pa_assert(c); - if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_UINT32, &default_sample_rate) < 0) - return; + dbus_message_iter_get_basic(iter, &default_sample_rate); if (default_sample_rate <= 0 || default_sample_rate > PA_RATE_MAX) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample rate."); @@ -639,13 +641,14 @@ static void handle_get_fallback_sink(DBusConnection *conn, DBusMessage *msg, voi pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); } -static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { +static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { pa_dbusiface_core *c = userdata; pa_dbusiface_device *fallback_sink; const char *object_path; pa_assert(conn); pa_assert(msg); + pa_assert(iter); pa_assert(c); if (!c->fallback_sink) { @@ -654,8 +657,7 @@ static void handle_set_fallback_sink(DBusConnection *conn, DBusMessage *msg, voi return; } - if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path) < 0) - return; + dbus_message_iter_get_basic(iter, &object_path); if (!(fallback_sink = pa_hashmap_get(c->sinks_by_path, object_path))) { pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", object_path); @@ -727,13 +729,14 @@ static void handle_get_fallback_source(DBusConnection *conn, DBusMessage *msg, v pa_dbus_send_basic_variant_reply(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path); } -static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, void *userdata) { +static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, void *userdata) { pa_dbusiface_core *c = userdata; pa_dbusiface_device *fallback_source; const char *object_path; pa_assert(conn); pa_assert(msg); + pa_assert(iter); pa_assert(c); if (!c->fallback_source) { @@ -742,8 +745,7 @@ static void handle_set_fallback_source(DBusConnection *conn, DBusMessage *msg, v return; } - if (pa_dbus_get_basic_set_property_arg(conn, msg, DBUS_TYPE_OBJECT_PATH, &object_path) < 0) - return; + dbus_message_iter_get_basic(iter, &object_path); if (!(fallback_source = pa_hashmap_get(c->sources_by_path, object_path))) { pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", object_path); @@ -1117,19 +1119,12 @@ static void handle_get_card_by_name(DBusConnection *conn, DBusMessage *msg, void pa_card *card; pa_dbusiface_card *dbus_card; const char *object_path; - DBusError error; pa_assert(conn); pa_assert(msg); pa_assert(c); - dbus_error_init(&error); - - if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &card_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - return; - } + pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &card_name, DBUS_TYPE_INVALID)); if (!(card = pa_namereg_get(c->core, card_name, PA_NAMEREG_CARD))) { pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such card."); @@ -1149,19 +1144,12 @@ static void handle_get_sink_by_name(DBusConnection *conn, DBusMessage *msg, void pa_sink *sink; pa_dbusiface_device *dbus_sink; const char *object_path; - DBusError error; pa_assert(conn); pa_assert(msg); pa_assert(c); - dbus_error_init(&error); - - if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &sink_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - return; - } + pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &sink_name, DBUS_TYPE_INVALID)); if (!(sink = pa_namereg_get(c->core, sink_name, PA_NAMEREG_SINK))) { pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such sink.", sink_name); @@ -1181,19 +1169,12 @@ static void handle_get_source_by_name(DBusConnection *conn, DBusMessage *msg, vo pa_source *source; pa_dbusiface_device *dbus_source; const char *object_path; - DBusError error; pa_assert(conn); pa_assert(msg); pa_assert(c); - dbus_error_init(&error); - - if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &source_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - return; - } + pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &source_name, DBUS_TYPE_INVALID)); if (!(source = pa_namereg_get(c->core, source_name, PA_NAMEREG_SOURCE))) { pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "%s: No such source.", source_name); @@ -1213,19 +1194,12 @@ static void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, vo pa_scache_entry *sample; pa_dbusiface_sample *dbus_sample; const char *object_path; - DBusError error; pa_assert(conn); pa_assert(msg); pa_assert(c); - dbus_error_init(&error); - - if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &sample_name, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - return; - } + pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &sample_name, DBUS_TYPE_INVALID)); if (!(sample = pa_namereg_get(c->core, sample_name, PA_NAMEREG_SAMPLE))) { pa_dbus_send_error(conn, msg, PA_DBUS_ERROR_NOT_FOUND, "No such sample."); @@ -1242,17 +1216,18 @@ static void handle_get_sample_by_name(DBusConnection *conn, DBusMessage *msg, vo static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_dbusiface_core *c = userdata; DBusMessageIter msg_iter; + DBusMessageIter array_iter; const char *name; dbus_uint32_t sample_format; dbus_uint32_t sample_rate; const dbus_uint32_t *channels; - unsigned n_channels; + int n_channels; const dbus_uint32_t *default_volume; - unsigned n_volume_entries; + int n_volume_entries; pa_proplist *property_list; const uint8_t *data; - unsigned data_length; - unsigned i; + int data_length; + int i; pa_sample_spec ss; pa_channel_map map; pa_memchunk chunk; @@ -1267,31 +1242,29 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u chunk.memblock = NULL; - if (!dbus_message_iter_init(msg, &msg_iter)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments."); - return; - } - - if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_STRING, &name) < 0) - return; + pa_assert_se(dbus_message_iter_init(msg, &msg_iter)); + dbus_message_iter_get_basic(&msg_iter, &name); - if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &sample_format) < 0) - return; + pa_assert_se(dbus_message_iter_next(&msg_iter)); + dbus_message_iter_get_basic(&msg_iter, &sample_format); - if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &sample_rate) < 0) - return; + pa_assert_se(dbus_message_iter_next(&msg_iter)); + dbus_message_iter_get_basic(&msg_iter, &sample_rate); - if (pa_dbus_get_fixed_array_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &channels, &n_channels) < 0) - return; + pa_assert_se(dbus_message_iter_next(&msg_iter)); + dbus_message_iter_recurse(&msg_iter, &array_iter); + dbus_message_iter_get_fixed_array(&array_iter, &channels, &n_channels); - if (pa_dbus_get_fixed_array_arg(conn, msg, &msg_iter, DBUS_TYPE_UINT32, &default_volume, &n_volume_entries) < 0) - return; + pa_assert_se(dbus_message_iter_next(&msg_iter)); + dbus_message_iter_recurse(&msg_iter, &array_iter); + dbus_message_iter_get_fixed_array(&array_iter, &default_volume, &n_volume_entries); + pa_assert_se(dbus_message_iter_next(&msg_iter)); if (!(property_list = pa_dbus_get_proplist_arg(conn, msg, &msg_iter))) return; - if (pa_dbus_get_fixed_array_arg(conn, msg, &msg_iter, DBUS_TYPE_BYTE, &data, &data_length) < 0) - goto finish; + dbus_message_iter_recurse(&msg_iter, &array_iter); + dbus_message_iter_get_fixed_array(&array_iter, &data, &data_length); if (sample_format >= PA_SAMPLE_MAX) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid sample format."); @@ -1303,14 +1276,14 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u goto finish; } - if (n_channels == 0) { + if (n_channels <= 0) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Empty channel map."); goto finish; } - if (n_channels > PA_CHANNELS_MAX) { + if (n_channels > (int) PA_CHANNELS_MAX) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "Too many channels: %u. The maximum is %u.", n_channels, PA_CHANNELS_MAX); + "Too many channels: %i. The maximum is %u.", n_channels, PA_CHANNELS_MAX); goto finish; } @@ -1323,13 +1296,14 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u if (n_volume_entries != 0 && n_volume_entries != n_channels) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "The channels and default_volume arguments have different number of elements."); + "The channels and default_volume arguments have different number of elements (%i and %i, resp).", + n_channels, n_volume_entries); goto finish; } for (i = 0; i < n_volume_entries; ++i) { if (default_volume[i] > PA_VOLUME_MAX) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid volume: %u.", default_volume[i]); goto finish; } } @@ -1340,7 +1314,9 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u } if (data_length > PA_SCACHE_ENTRY_SIZE_MAX) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too big sample."); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, + "Too big sample: %i bytes. The maximum sample length is %u bytes.", + data_length, PA_SCACHE_ENTRY_SIZE_MAX); goto finish; } @@ -1348,9 +1324,13 @@ static void handle_upload_sample(DBusConnection *conn, DBusMessage *msg, void *u ss.rate = sample_rate; ss.channels = n_channels; + pa_assert(pa_sample_spec_valid(&ss)); + if (!pa_frame_aligned(data_length, &ss)) { + char buf[PA_SAMPLE_SPEC_SNPRINT_MAX]; pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "The sample length in bytes doesn't align with the sample format and channels."); + "The sample length (%i bytes) doesn't align with the sample format and channels (%s).", + data_length, pa_sample_spec_snprint(buf, sizeof(buf), &ss)); goto finish; } @@ -1414,15 +1394,15 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use DBusMessageIter msg_iter; DBusMessageIter dict_iter; DBusMessageIter dict_entry_iter; - char *name; - const char *key; - const char *value; - char *escaped_value; + char *name = NULL; + const char *key = NULL; + const char *value = NULL; + char *escaped_value = NULL; pa_strbuf *arg_buffer = NULL; - pa_module *module; - pa_dbusiface_module *dbus_module; - const char *object_path; - int arg_type; + char *arg_string = NULL; + pa_module *module = NULL; + pa_dbusiface_module *dbus_module = NULL; + const char *object_path = NULL; pa_assert(conn); pa_assert(msg); @@ -1433,35 +1413,12 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use return; } - if (!dbus_message_iter_init(msg, &msg_iter)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Too few arguments."); - return; - } - - if (pa_dbus_get_basic_arg(conn, msg, &msg_iter, DBUS_TYPE_STRING, &name) < 0) - return; - - arg_type = dbus_message_iter_get_arg_type(&msg_iter); - if (arg_type != DBUS_TYPE_ARRAY) { - if (arg_type == DBUS_TYPE_INVALID) - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "Too few arguments. A dictionary from strings to strings was expected."); - else - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "Wrong argument type: '%c'. An dictionary from strings to strings was expected.", - (char) arg_type); - return; - } - - arg_type = dbus_message_iter_get_element_type(&msg_iter); - if (arg_type != DBUS_TYPE_DICT_ENTRY) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "Wrong array element type: '%c'. A dict entry (string to string) was expected.", (char) arg_type); - return; - } + pa_assert_se(dbus_message_iter_init(msg, &msg_iter)); + dbus_message_iter_get_basic(&msg_iter, &name); arg_buffer = pa_strbuf_new(); + pa_assert_se(dbus_message_iter_next(&msg_iter)); dbus_message_iter_recurse(&msg_iter, &dict_iter); while (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_INVALID) { @@ -1470,41 +1427,26 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use dbus_message_iter_recurse(&dict_iter, &dict_entry_iter); - arg_type = dbus_message_iter_get_arg_type(&dict_entry_iter); - if (arg_type != DBUS_TYPE_STRING) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "Wrong dict key type: '%c'. A string was expected.", (char) arg_type); - goto finish; - } - dbus_message_iter_get_basic(&dict_entry_iter, &key); - dbus_message_iter_next(&dict_entry_iter); if (strlen(key) <= 0 || !pa_ascii_valid(key) || contains_space(key)) { pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Invalid module argument name: %s", key); goto finish; } - arg_type = dbus_message_iter_get_arg_type(&dict_entry_iter); - if (arg_type != DBUS_TYPE_STRING) { - if (arg_type == DBUS_TYPE_INVALID) - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "Dict value missing."); - else - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, - "Wrong dict value type: '%c'. A string was expected.", (char) arg_type); - goto finish; - } - + pa_assert_se(dbus_message_iter_next(&dict_entry_iter)); dbus_message_iter_get_basic(&dict_entry_iter, &value); - dbus_message_iter_next(&dict_iter); - escaped_value = pa_escape(value, "\""); pa_strbuf_printf(arg_buffer, "%s=\"%s\"", key, escaped_value); pa_xfree(escaped_value); + + dbus_message_iter_next(&dict_iter); } - if (!(module = pa_module_load(c->core, name, pa_strbuf_tostring(arg_buffer)))) { + arg_string = pa_strbuf_tostring(arg_buffer); + + if (!(module = pa_module_load(c->core, name, arg_string))) { pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "Failed to load module."); goto finish; } @@ -1519,6 +1461,8 @@ static void handle_load_module(DBusConnection *conn, DBusMessage *msg, void *use finish: if (arg_buffer) pa_strbuf_free(arg_buffer); + + pa_xfree(arg_string); } static void handle_exit(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -1543,47 +1487,32 @@ static void handle_listen_for_signal(DBusConnection *conn, DBusMessage *msg, voi const char *signal; char **objects = NULL; int n_objects; - DBusError error; pa_assert(conn); pa_assert(msg); pa_assert(c); - dbus_error_init(&error); - - if (!dbus_message_get_args(msg, &error, - DBUS_TYPE_STRING, &signal, - DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, - DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - goto finish; - } + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &signal, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objects, &n_objects, + DBUS_TYPE_INVALID)); pa_dbus_protocol_add_signal_listener(c->dbus_protocol, conn, *signal ? signal : NULL, objects, n_objects); pa_dbus_send_empty_reply(conn, msg); -finish: dbus_free_string_array(objects); } static void handle_stop_listening_for_signal(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_dbusiface_core *c = userdata; const char *signal; - DBusError error; pa_assert(conn); pa_assert(msg); pa_assert(c); - dbus_error_init(&error); - - if (!dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &signal, DBUS_TYPE_INVALID)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - return; - } + pa_assert_se(dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &signal, DBUS_TYPE_INVALID)); pa_dbus_protocol_remove_signal_listener(c->dbus_protocol, conn, *signal ? signal : NULL); -- cgit From 411feaed15edcef685e88582d76eddc5acfd965e Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Mon, 31 Aug 2009 09:14:50 +0300 Subject: dbusiface-core: Add signals FallbackSinkUnset and FallbackSourceUnset. --- src/modules/dbus/iface-core.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/modules/dbus/iface-core.c') diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c index 0507ac9c..169e8e55 100644 --- a/src/modules/dbus/iface-core.c +++ b/src/modules/dbus/iface-core.c @@ -247,9 +247,11 @@ enum signal_index { SIGNAL_NEW_SINK, SIGNAL_SINK_REMOVED, SIGNAL_FALLBACK_SINK_UPDATED, + SIGNAL_FALLBACK_SINK_UNSET, SIGNAL_NEW_SOURCE, SIGNAL_SOURCE_REMOVED, SIGNAL_FALLBACK_SOURCE_UPDATED, + SIGNAL_FALLBACK_SOURCE_UNSET, SIGNAL_NEW_PLAYBACK_STREAM, SIGNAL_PLAYBACK_STREAM_REMOVED, SIGNAL_NEW_RECORD_STREAM, @@ -292,9 +294,11 @@ static pa_dbus_signal_info signals[SIGNAL_MAX] = { [SIGNAL_NEW_SINK] = { .name = "NewSink", .arguments = new_sink_args, .n_arguments = 1 }, [SIGNAL_SINK_REMOVED] = { .name = "SinkRemoved", .arguments = sink_removed_args, .n_arguments = 1 }, [SIGNAL_FALLBACK_SINK_UPDATED] = { .name = "FallbackSinkUpdated", .arguments = fallback_sink_updated_args, .n_arguments = 1 }, + [SIGNAL_FALLBACK_SINK_UNSET] = { .name = "FallbackSinkUnset", .arguments = NULL, .n_arguments = 0 }, [SIGNAL_NEW_SOURCE] = { .name = "NewSource", .arguments = new_source_args, .n_arguments = 1 }, [SIGNAL_SOURCE_REMOVED] = { .name = "SourceRemoved", .arguments = source_removed_args, .n_arguments = 1 }, [SIGNAL_FALLBACK_SOURCE_UPDATED] = { .name = "FallbackSourceUpdated", .arguments = fallback_source_updated_args, .n_arguments = 1 }, + [SIGNAL_FALLBACK_SOURCE_UNSET] = { .name = "FallbackSourceUnset", .arguments = NULL, .n_arguments = 0 }, [SIGNAL_NEW_PLAYBACK_STREAM] = { .name = "NewPlaybackStream", .arguments = new_playback_stream_args, .n_arguments = 1 }, [SIGNAL_PLAYBACK_STREAM_REMOVED] = { .name = "PlaybackStreamRemoved", .arguments = playback_stream_removed_args, .n_arguments = 1 }, [SIGNAL_NEW_RECORD_STREAM] = { .name = "NewRecordStream", .arguments = new_record_stream_args, .n_arguments = 1 }, @@ -1555,6 +1559,14 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); signal = NULL; + + } else if (!new_fallback_sink) { + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SINK_UNSET].name))); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; } } @@ -1574,6 +1586,14 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3 pa_dbus_protocol_send_signal(c->dbus_protocol, signal); dbus_message_unref(signal); signal = NULL; + + } else if (!new_fallback_source) { + pa_assert_se((signal = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH, + PA_DBUS_CORE_INTERFACE, + signals[SIGNAL_FALLBACK_SOURCE_UNSET].name))); + pa_dbus_protocol_send_signal(c->dbus_protocol, signal); + dbus_message_unref(signal); + signal = NULL; } } break; -- cgit