From 3a177b411fdebff386cf1221b8da6e8f4bb94bc1 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 24 Jul 2018 14:03:11 +0900 Subject: [PATCH 01/16] device-manager-db: Fix passing argument after free SVACE issue (#348982) [Version] 11.1.21 [Issue Type] Bug fix Change-Id: If74b99d49314c7839637875a21fc2e93bfa3ecbc Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-db.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 761c24e..ed60ede 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.20 +Version: 11.1.21 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-db.c b/src/device-manager-db.c index 0ed37a8..f1cfaa8 100644 --- a/src/device-manager-db.c +++ b/src/device-manager-db.c @@ -124,6 +124,9 @@ prefer_entry* read_prefer_entry(pa_device_manager *dm, const char *key) { PA_TAG_INVALID)) { pa_log_error("failed to get preference values from tagstruct"); pa_xfree(e); + pa_tagstruct_free(t); + pa_datum_free(&db_data); + return NULL; } pa_tagstruct_free(t); -- 2.7.4 From 929885880d66e03b1a42fd2aaf5a9adebe89a87c Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Thu, 26 Jul 2018 12:21:46 +0900 Subject: [PATCH 02/16] device-manager-dbus: Functions related to DBus are moved to a new file Files are added as below: device-manager-dbus.c device-manager-dbus-priv.h [Version] 11.1.22 [Issue type] Refactor Change-Id: I3fa759f4c3973b2106d2b5d2b1b2e9db6b5bbd7a Signed-off-by: Sangchul Lee --- Makefile.am | 1 + packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-db-priv.h | 7 + src/device-manager-dbus-priv.h | 34 + src/device-manager-dbus.c | 1823 ++++++++++++++++++++++++++++ src/device-manager-priv.h | 68 +- src/device-manager.c | 1964 +------------------------------ src/device-manager.h | 2 +- src/stream-manager-dbus-priv.h | 4 +- src/stream-manager-dbus.c | 4 +- src/stream-manager.c | 4 +- 11 files changed, 1990 insertions(+), 1923 deletions(-) create mode 100644 src/device-manager-dbus-priv.h create mode 100644 src/device-manager-dbus.c diff --git a/Makefile.am b/Makefile.am index 2b83bf9..aa0a418 100644 --- a/Makefile.am +++ b/Makefile.am @@ -110,6 +110,7 @@ module_tizenaudio_policy_la_SOURCES = \ src/stream-manager-restriction.c src/stream-manager-restriction-priv.h \ src/stream-manager-filter.c src/stream-manager-volume-filter.h \ src/device-manager.c src/device-manager.h src/device-manager-priv.h \ + src/device-manager-dbus.c src/device-manager-dbus-priv.h \ src/device-manager-db.c src/device-manager-db-priv.h \ src/tizen-device.c src/tizen-device.h src/tizen-device-def.c src/tizen-device-def.h \ src/subscribe-observer.c src/subscribe-observer.h diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index ed60ede..9f7c6c3 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.21 +Version: 11.1.22 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-db-priv.h b/src/device-manager-db-priv.h index 5bd20b8..7bed9b2 100644 --- a/src/device-manager-db-priv.h +++ b/src/device-manager-db-priv.h @@ -24,6 +24,13 @@ #include "device-manager.h" +#define FILL_SAMPLE_SPEC_WITH_PREFER_ENTRY(x_spec, x_entry) \ +do { \ + x_spec.format = x_entry->format; \ + x_spec.rate = x_entry->rate; \ + x_spec.channels = 2; \ +} while(0) + typedef struct _prefer_entry { bool avoid_resampling; pa_sample_format_t format; diff --git a/src/device-manager-dbus-priv.h b/src/device-manager-dbus-priv.h new file mode 100644 index 0000000..92a503c --- /dev/null +++ b/src/device-manager-dbus-priv.h @@ -0,0 +1,34 @@ +/*** + This file is part of PulseAudio. + + Copyright 2018 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifndef foodevicemanagerdbusprivfoo +#define foodevicemanagerdbusprivfoo +#ifdef HAVE_DBUS + +void send_device_connection_changed_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm); +void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *device, int changed_type, pa_device_manager *dm); +void send_device_state_changed_signal(uint32_t event_id, pa_tz_device *device, bool activated, pa_device_manager *dm); +void send_device_running_changed_signal(uint32_t event_id, pa_tz_device *device, bool is_running, pa_device_manager *dm); +void init_dm_dbus(pa_device_manager *dm); +void deinit_dm_dbus(pa_device_manager *dm); + +#endif +#endif \ No newline at end of file diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c new file mode 100644 index 0000000..135a110 --- /dev/null +++ b/src/device-manager-dbus.c @@ -0,0 +1,1823 @@ +/*** + This file is part of PulseAudio. + + Copyright 2018 Sangchul Lee + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_DBUS + +#include +#include +#include +#include +#include + +#include "stream-manager.h" +#include "device-manager.h" +#include "device-manager-priv.h" +#include "device-manager-db-priv.h" + +/* Dbus defines */ +#define DBUS_INTERFACE_DEVICE_MANAGER "org.pulseaudio.DeviceManager" +#define DBUS_OBJECT_DEVICE_MANAGER "/org/pulseaudio/DeviceManager" + +#define DBUS_INTERFACE_DEVICED_SYSNOTI "org.tizen.system.deviced.SysNoti" +#define DBUS_OBJECT_DEVICED_SYSNOTI "/Org/Tizen/System/DeviceD/SysNoti" + +#define DBUS_INTERFACE_SOUND_SERVER "org.tizen.SoundServer1" +#define DBUS_OBJECT_SOUND_SERVER "/org/tizen/SoundServer1" + +#define DBUS_SERVICE_BLUEZ "org.bluez" +#define DBUS_INTERFACE_BLUEZ_HEADSET "org.bluez.Headset" +#define DBUS_INTERFACE_BLUEZ_DEVICE "org.bluez.Device1" +#define DBUS_OBJECT_BLUEZ "/org/bluez" + +#define DBUS_INTERFACE_MIRRORING_SERVER "org.tizen.scmirroring.server" +#define DBUS_OBJECT_MIRRORING_SERVER "/org/tizen/scmirroring/server" + +#define DBUS_SERVICE_HFP_AGENT "org.bluez.ag_agent" +#define DBUS_OBJECT_HFP_AGENT "/org/bluez/hfp_agent" +#define DBUS_INTERFACE_HFP_AGENT "Org.Hfp.App.Interface" + +#define DEVICE_MANAGER_INTROSPECT_XML \ + DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ + "\n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " " \ + " " \ + " " \ + " " \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ + "\n" + +#define FILTER_DEVICED_SYSNOTI \ + "type='signal'," \ + " interface='" DBUS_INTERFACE_DEVICED_SYSNOTI "'" + +#define FILTER_SOUND_SERVER \ + "type='signal'," \ + " interface='" DBUS_INTERFACE_SOUND_SERVER "'" + +#define FILTER_MIRRORING \ + "type='signal'," \ + " interface='" DBUS_INTERFACE_MIRRORING_SERVER "', member='miracast_wfd_source_status_changed'" + +#define FILTER_BLUEZ \ + "type='signal'," \ + " interface='" DBUS_INTERFACE_BLUEZ_HEADSET "', member='PropertyChanged'" + +#define FILL_SAMPLE_SPEC_WITH_SELECTED(x_spec, x_sink) \ +do { \ + x_spec.format = x_sink->selected_sample_format; \ + x_spec.rate = x_sink->selected_sample_rate; \ + x_spec.channels = 2; \ +} while(0) + +/*** Defines for method handle ***/ +static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_device_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_specified_stream(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_set_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_unload_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_unload_sink_with_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_get_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_dump_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata); + +static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name); + +enum method_handler_index { + METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST, + METHOD_HANDLER_GET_DEVICE_BY_ID, + METHOD_HANDLER_IS_STREAM_ON_DEVICE, + METHOD_HANDLER_GET_BT_A2DP_STATUS, + METHOD_HANDLER_LOAD_SINK, + METHOD_HANDLER_UNLOAD_SINK, + METHOD_HANDLER_UNLOAD_SINK_WITH_DEVICE_STRING, + METHOD_HANDLER_GET_DEVICE_STRING, + METHOD_HANDLER_GET_SUPPORTED_SAMPLE_FORMATS, + METHOD_HANDLER_SET_SAMPLE_FORMAT, + METHOD_HANDLER_GET_SAMPLE_FORMAT, + METHOD_HANDLER_GET_SUPPORTED_SAMPLE_RATES, + METHOD_HANDLER_SET_SAMPLE_RATE, + METHOD_HANDLER_GET_SAMPLE_RATE, + METHOD_HANDLER_SET_SPECIFIC_STREAM_ONLY, + METHOD_HANDLER_GET_SPECIFIED_STREAM, + METHOD_HANDLER_SET_AVOID_RESAMPLING, + METHOD_HANDLER_GET_AVOID_RESAMPLING, + METHOD_HANDLER_DUMP_DEVICE_LIST, + METHOD_HANDLER_STATUS_TEST, + METHOD_HANDLER_MAX +}; + +static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { + [METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST] = { + .method_name = "GetConnectedDeviceList", + .receive_cb = handle_get_connected_device_list }, + [METHOD_HANDLER_GET_DEVICE_BY_ID] = { + .method_name = "GetDeviceById", + .receive_cb = handle_get_device_by_id }, + [METHOD_HANDLER_IS_STREAM_ON_DEVICE] = { + .method_name = "IsStreamOnDevice", + .receive_cb = handle_is_stream_on_device }, + [METHOD_HANDLER_GET_BT_A2DP_STATUS] = { + .method_name = "GetBTA2DPStatus", + .receive_cb = handle_get_bt_a2dp_status }, + [METHOD_HANDLER_LOAD_SINK] = { + .method_name = "LoadSink", + .receive_cb = handle_load_sink }, + [METHOD_HANDLER_UNLOAD_SINK] = { + .method_name = "UnloadSink", + .receive_cb = handle_unload_sink }, + [METHOD_HANDLER_UNLOAD_SINK_WITH_DEVICE_STRING] = { + .method_name = "UnloadSinkWithDeviceString", + .receive_cb = handle_unload_sink_with_device_string }, + [METHOD_HANDLER_GET_DEVICE_STRING] = { + .method_name = "GetDeviceString", + .receive_cb = handle_get_device_string }, + [METHOD_HANDLER_GET_SUPPORTED_SAMPLE_FORMATS] = { + .method_name = "GetSupportedSampleFormats", + .receive_cb = handle_get_supported_sample_formats }, + [METHOD_HANDLER_SET_SAMPLE_FORMAT] = { + .method_name = "SetSampleFormat", + .receive_cb = handle_set_sample_format }, + [METHOD_HANDLER_GET_SAMPLE_FORMAT] = { + .method_name = "GetSampleFormat", + .receive_cb = handle_get_sample_format }, + [METHOD_HANDLER_GET_SUPPORTED_SAMPLE_RATES] = { + .method_name = "GetSupportedSampleRates", + .receive_cb = handle_get_supported_sample_rates }, + [METHOD_HANDLER_SET_SAMPLE_RATE] = { + .method_name = "SetSampleRate", + .receive_cb = handle_set_sample_rate }, + [METHOD_HANDLER_GET_SAMPLE_RATE] = { + .method_name = "GetSampleRate", + .receive_cb = handle_get_sample_rate }, + [METHOD_HANDLER_SET_SPECIFIC_STREAM_ONLY] = { + .method_name = "SetSpecificStreamOnly", + .receive_cb = handle_set_specific_stream_only }, + [METHOD_HANDLER_GET_SPECIFIED_STREAM] = { + .method_name = "GetSpecifiedStream", + .receive_cb = handle_get_specified_stream }, + [METHOD_HANDLER_SET_AVOID_RESAMPLING] = { + .method_name = "SetAvoidResampling", + .receive_cb = handle_set_avoid_resampling }, + [METHOD_HANDLER_GET_AVOID_RESAMPLING] = { + .method_name = "GetAvoidResampling", + .receive_cb = handle_get_avoid_resampling }, + [METHOD_HANDLER_DUMP_DEVICE_LIST] = { + .method_name = "DumpDeviceList", + .receive_cb = handle_dump_device_list }, + [METHOD_HANDLER_STATUS_TEST] = { + .method_name = "TestStatusChange", + .receive_cb = handle_test_device_status_change }, +}; + +static void save_preference(pa_device_manager *dm, pa_sink *sink) { + const char *key; + prefer_entry e; + + pa_assert(dm); + pa_assert(sink); + + e.avoid_resampling = sink->avoid_resampling; + e.format = sink->selected_sample_format; + e.rate = sink->selected_sample_rate; + if ((key = build_key_from_proplist(sink->proplist))) + write_prefer_entry(dm, key, &e); +} + +/* + Handle device disconnection detected through dbus. + First, update device-status hashmap. + And if there is device which has the device_type, remove it. +*/ +static int handle_device_disconnected(pa_device_manager *dm, const char *type, const char *system_id) { + pa_tz_device *device; + + pa_assert(dm); + pa_assert(dm->device_status); + + pa_log_info("Device type(%s) system_id(%s) disconnected", + type, pa_strempty(system_id)); + + device = device_list_get_device(dm, type, system_id); + if (!device) { + pa_log_error("Disconnection detected but no device for that"); + return -1; + } + + pa_tz_device_free(device); + + return 0; +} + +/* + look detected status which is external value, make conversion to internal consistent value, and handle it + device_type, which type of device is detected + system_id : system_id among same device types for support multi-device +*/ +static int handle_device_status_changed(pa_device_manager *dm, const char *type, + const char *name, const char *system_id, device_detected_type_t detected) { + pa_assert(dm); + + pa_log_info("Device Status Changed, type(%s) system_id(%s), detected_type(%d)", + type, pa_strempty(system_id), detected); + + if (!device_type_is_valid(type)) { + pa_log_error("Invalid device type %s", type); + return -1; + } else if (device_type_is_equal(type, DEVICE_TYPE_BT_SCO)) { + device_set_detected(dm, type, name, system_id, detected); + if (detected == DEVICE_DISCONNECTED) + handle_device_disconnected(dm, type, system_id); + else + handle_device_connected(dm, type, name, system_id, detected); + } else if (device_type_is_need_detect(type)) { + device_set_detected(dm, type, name, system_id, detected); + if (detected == DEVICE_DISCONNECTED) + handle_device_disconnected(dm, type, system_id); + else + handle_device_connected(dm, type, name, system_id, detected); + } else { + pa_log_debug("No need to detect type %s", type); + } + + return 0; +} + +static int _translate_external_value(const char *type, int value, device_detected_type_t *detected) { + + if (!type || !detected) { + pa_log_error("Invalid Parameter for translate"); + return -1; + } + + if (device_type_is_equal(DEVICE_TYPE_AUDIO_JACK, type)) { + if (value == EARJACK_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == EARJACK_TYPE_SPK_ONLY) + *detected = DEVICE_CONNECTED_AUDIO_JACK_3P; + else if (value == EARJACK_TYPE_SPK_WITH_MIC) + *detected = DEVICE_CONNECTED_AUDIO_JACK_4P; + else + return -1; + } else if (device_type_is_equal(DEVICE_TYPE_HDMI, type)) { + if (value == HDMI_AUDIO_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == HDMI_AUDIO_AVAILABLE) + *detected = DEVICE_CONNECTED; + else + return -1; + } else if (device_type_is_equal(DEVICE_TYPE_FORWARDING, type)) { + if (value == FORWARDING_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == FORWARDING_CONNECTED) + *detected = DEVICE_CONNECTED; + else + return -1; + } else if (device_type_is_equal(DEVICE_TYPE_BT_SCO, type)) { + if (value == BT_SCO_DISCONNECTED) + *detected = DEVICE_DISCONNECTED; + else if (value == BT_SCO_CONNECTED) + *detected = DEVICE_CONNECTED_SCO; + else + return -1; + } + + return 0; +} + +static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DBusMessage *s, void *userdata) { + DBusError error; + int status = 0; + pa_device_manager *dm = (pa_device_manager *) userdata; + device_detected_type_t detected; + + pa_assert(userdata); + + if (dbus_message_get_type(s) != DBUS_MESSAGE_TYPE_SIGNAL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + pa_log_info("Device detect handler : Path(%s) Intf(%s) Member(%s) Signature(%s)", + dbus_message_get_path(s), dbus_message_get_interface(s), dbus_message_get_member(s), dbus_message_get_signature(s)); + + dbus_error_init(&error); + + if (dbus_message_is_signal(s, DBUS_INTERFACE_DEVICED_SYSNOTI, "ChangedEarjack")) { + if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { + goto fail; + } else { + if (_translate_external_value(DEVICE_TYPE_AUDIO_JACK, status, &detected) < 0) { + pa_log_warn("failed to translate audio-jack detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_AUDIO_JACK, NULL, NULL, detected); + } + } else if (dbus_message_is_signal(s, DBUS_INTERFACE_DEVICED_SYSNOTI, "ChangedHDMIAudio")) { + if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { + goto fail; + } else { + if (_translate_external_value(DEVICE_TYPE_HDMI, status, &detected) < 0) { + pa_log_warn("failed to translate HDMI detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_HDMI, NULL, NULL, detected); + } + } else if (dbus_message_is_signal(s, DBUS_INTERFACE_MIRRORING_SERVER, "miracast_wfd_source_status_changed")) { + if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { + goto fail; + } else { + if (_translate_external_value(DEVICE_TYPE_FORWARDING, status, &detected) < 0) { + pa_log_warn("failed to translate forwarding detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_FORWARDING, NULL, NULL, detected); + } + } else if (dbus_message_is_signal(s, DBUS_INTERFACE_BLUEZ_HEADSET, "PropertyChanged")) { + DBusMessageIter msg_iter, variant_iter; + char *property_name; + + pa_log_debug("Got %s PropertyChanged signal", DBUS_INTERFACE_BLUEZ_HEADSET); + dbus_message_iter_init(s, &msg_iter); + if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_STRING) { + pa_log_error("Property name not string"); + goto fail; + } + dbus_message_iter_get_basic(&msg_iter, &property_name); + pa_log_info("Changed Property name : %s", property_name); + + if (!dbus_message_iter_next(&msg_iter)) { + pa_log_debug("Property value missing"); + goto fail; + } + + if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_VARIANT) { + pa_log_debug("Property value not a variant."); + goto fail; + } + + dbus_message_iter_recurse(&msg_iter, &variant_iter); + + if (DBUS_TYPE_BOOLEAN == dbus_message_iter_get_arg_type(&variant_iter)) { + dbus_bool_t value; + char *name = NULL; + dbus_message_iter_get_basic(&variant_iter, &value); + if (pa_streq(property_name, "Connected")) { + pa_log_info("HFP Connection : %d", value); + if (value) { + method_call_bt_get_name(c, dbus_message_get_path(s), &name); + status = BT_SCO_CONNECTED; + } else { + status = BT_SCO_DISCONNECTED; + } + if (_translate_external_value(DEVICE_TYPE_BT_SCO, status, &detected) < 0) { + pa_log_warn("failed to translate bt-sco detected value"); + goto fail; + } + handle_device_status_changed(dm, DEVICE_TYPE_BT_SCO, + name, dbus_message_get_path(s), detected); + } else if (pa_streq(property_name, "Playing")) { + pa_tz_device *device; + pa_log_info("SCO Playing : %d", value); + if ((device = device_list_get_device(dm, DEVICE_TYPE_BT_SCO, NULL)) != NULL) { + device->sco_opened = value; + if (value) { + /* update BT band/nrec information */ + bool is_wide_band = false; + bool nrec = false; + pa_tz_device_sco_get_property(device, &is_wide_band, &nrec); + pa_log_info("got new wideband:%d, nrec:%d", is_wide_band, nrec); + + UPDATE_HAL_ROUTE_OPTION(dm->hal_interface, NULL, "bt-wideband", is_wide_band); + UPDATE_HAL_ROUTE_OPTION(dm->hal_interface, NULL, "bt-nrec", nrec); + } + } + UPDATE_HAL_ROUTE_OPTION(dm->hal_interface, NULL, "bt-sco-ready", value); + } + } + } else { + pa_log_debug("Unknown message, not handle it"); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + pa_log_debug("Dbus Message handled"); + + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_HANDLED; + +fail: + pa_log_error("Fail to handle dbus signal"); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static bool device_is_match_direction(pa_tz_device *device, int direction_mask) { + dm_device_direction_t direction; + + if (direction_mask == DEVICE_IO_DIRECTION_FLAGS || direction_mask == 0) + return true; + + direction = pa_tz_device_get_direction(device); + + if ((direction_mask & DEVICE_IO_DIRECTION_IN_FLAG) && (direction & DM_DEVICE_DIRECTION_IN)) + return true; + if ((direction_mask & DEVICE_IO_DIRECTION_OUT_FLAG) && (direction & DM_DEVICE_DIRECTION_OUT)) + return true; + if ((direction_mask & DEVICE_IO_DIRECTION_BOTH_FLAG) && (direction == DM_DEVICE_DIRECTION_BOTH)) + return true; + + return false; +} + +static bool device_is_match_state(pa_tz_device *device, int state_mask) { + dm_device_state_t state; + + if (state_mask == DEVICE_STATE_FLAGS || state_mask == 0) + return true; + + state = pa_tz_device_get_state(device); + + if ((state_mask & DEVICE_STATE_DEACTIVATED_FLAG) && (state == DM_DEVICE_STATE_DEACTIVATED)) + return true; + if ((state_mask & DEVICE_STATE_ACTIVATED_FLAG) && (state == DM_DEVICE_STATE_ACTIVATED)) + return true; + + return false; +} + +static bool device_is_match_type(pa_tz_device *device, int type_mask) { + char *type; + bool is_builtin; + + if (type_mask == DEVICE_TYPE_FLAGS || type_mask == 0) + return true; + + type = pa_tz_device_get_type(device); + is_builtin = device_type_is_builtin(type); + + if ((type_mask & DEVICE_TYPE_INTERNAL_FLAG) && is_builtin) + return true; + if ((type_mask & DEVICE_TYPE_EXTERNAL_FLAG) && !is_builtin) + return true; + + return false; +} + +static bool device_is_match_with_mask(pa_tz_device *device, int mask) { + pa_assert(device); + + if (mask == DEVICE_ALL_FLAG) + return true; + + return (device_is_match_direction(device, mask & DEVICE_IO_DIRECTION_FLAGS) && + device_is_match_state(device, mask & DEVICE_STATE_FLAGS) && + device_is_match_type(device, mask & DEVICE_TYPE_FLAGS)); +} + +static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name) { + const char *intf = DBUS_INTERFACE_BLUEZ_DEVICE, *prop = "Alias"; + DBusMessage *msg, *reply; + DBusMessageIter reply_iter, variant_iter; + DBusError err; + + pa_assert(conn); + pa_assert(device_path); + pa_assert(name); + + if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_BLUEZ, device_path, "org.freedesktop.DBus.Properties", "Get"))) { + pa_log_error("dbus method call failed"); + return -1; + } + + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &intf, + DBUS_TYPE_STRING, &prop, + DBUS_TYPE_INVALID); + + dbus_error_init(&err); + if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) { + pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_BLUEZ_DEVICE, "Get", err.message); + dbus_error_free(&err); + return -1; + } + + dbus_message_iter_init(reply, &reply_iter); + + if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_VARIANT) { + pa_log_error("Cannot get reply argument"); + return -1; + } + + dbus_message_iter_recurse(&reply_iter, &variant_iter); + + if (dbus_message_iter_get_arg_type(&variant_iter) == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&variant_iter, name); + } + + dbus_message_unref(reply); + return 0; +} + +static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + DBusMessageIter msg_iter, array_iter, device_iter; + pa_tz_device *device; + dm_device_state_t state; + uint32_t device_idx; + dbus_int32_t device_id, direction; + int mask; + char *type, *name; + dbus_int32_t vendor_id, product_id; + dbus_bool_t is_running; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + + dm = (pa_device_manager*) userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &mask, + DBUS_TYPE_INVALID)); + + pa_log_info("Get connected device list (mask : %d)", mask); + + dbus_message_iter_init_append(reply, &msg_iter); + pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiisiib)", &array_iter)); + + PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { + device_id = (dbus_int32_t)pa_tz_device_get_id(device); + state = pa_tz_device_get_state(device); + direction = pa_tz_device_get_direction(device); + type = pa_tz_device_get_type(device); + name = pa_tz_device_get_name(device); + vendor_id = (dbus_int32_t) pa_tz_device_get_vendor_id(device); + product_id = (dbus_int32_t) pa_tz_device_get_product_id(device); + product_id = (dbus_int32_t) pa_tz_device_get_product_id(device); + is_running = (dbus_bool_t) pa_tz_device_is_running(device); + if (device_is_match_with_mask(device, mask)) { + simple_device_dump(PA_LOG_INFO, "[MATCH]", device_id, type, name, direction, state); + pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &state); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &vendor_id); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &product_id); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_BOOLEAN, &is_running); + pa_assert_se(dbus_message_iter_close_container(&array_iter, &device_iter)); + } else { + simple_device_dump(PA_LOG_INFO, "[UNMATCH]", device_id, type, name, direction, state); + } + } + + pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); + + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_get_device_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *manager; + DBusMessage *reply; + DBusMessageIter msg_iter; + pa_tz_device *device; + dbus_int32_t device_id; + dbus_int32_t id, direction, state; + dbus_int32_t vendor_id, product_id; + char *type, *name; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + manager = (pa_device_manager*) userdata; + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Get device by id(%d)", device_id); + + if ((device = device_list_get_device_by_id(manager, device_id))) { + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dbus_message_iter_init_append(reply, &msg_iter); + + id = (dbus_int32_t)pa_tz_device_get_id(device); + state = pa_tz_device_get_state(device); + direction = pa_tz_device_get_direction(device); + type = pa_tz_device_get_type(device); + name = pa_tz_device_get_name(device); + vendor_id = (dbus_int32_t) pa_tz_device_get_vendor_id(device); + product_id = (dbus_int32_t) pa_tz_device_get_product_id(device); + + simple_device_dump(PA_LOG_INFO, "[GET_BY_ID]", device_id, type, name, direction, state); + + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &id); + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &type); + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &direction); + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &state); + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name); + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &vendor_id); + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &product_id); + + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); + } else { + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); + } +} + +static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *manager; + DBusMessage *reply; + pa_tz_device *device; + dbus_bool_t is_on = false; + dbus_int32_t stream_id, device_id; + pa_intset *stream_id_set; + int32_t stream_id_val; + int ret; + dm_device_state_t state; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + pa_log_info("Is stream on device"); + + manager = (pa_device_manager*) userdata; + + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &stream_id, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + if ((device = device_list_get_device_by_id(manager, device_id))) { + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + state = pa_tz_device_get_state(device); + if (state == DM_DEVICE_STATE_ACTIVATED) { + stream_id_set = pa_tz_device_get_stream_list(device); + PA_INTSET_FOREACH(stream_id_val, stream_id_set, ret) { + if (stream_id_val == stream_id) { + is_on = true; + pa_log_info("stream(%d) is on device(%d)", stream_id, device_id); + break; + } + } + pa_intset_free(stream_id_set); + } else { + pa_log_info("device(%d) is not activated, regard as no stream on it", device_id); + is_on = false; + } + + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_on, + DBUS_TYPE_INVALID)); + + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); + } else { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.Internal"); + } +} + +static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + pa_tz_device *device; + dbus_bool_t is_bt_on = false; + const char *bt_name = "none"; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + pa_log_info("Get BT A2DP list"); + + dm = (pa_device_manager*) userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + /* FIXME : Give system_id for multi device */ + if ((device = device_list_get_device(dm, DEVICE_TYPE_BT_A2DP, NULL)) != NULL) { + is_bt_on = true; + bt_name = pa_tz_device_get_name(device); + } + + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_bt_on, + DBUS_TYPE_STRING, &bt_name, + DBUS_TYPE_INVALID)); + + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + char *type, *role; + DBusMessage *reply = NULL; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *) userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &role, + DBUS_TYPE_INVALID)); + + pa_device_manager_load_sink(dm, type, role); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_unload_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + char *type, *role; + DBusMessage *reply = NULL; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *) userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &role, + DBUS_TYPE_INVALID)); + + pa_device_manager_unload_sink(dm, type, role); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_unload_sink_with_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + char *device_string; + DBusMessage *reply = NULL; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *) userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &device_string, + DBUS_TYPE_INVALID)); + + pa_device_manager_unload_sink_with_device_string(dm, device_string); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_get_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + char *type, *role; + const char *device_string; + dbus_bool_t is_playback; + DBusMessage *reply; + + dm = (pa_device_manager *) userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_BOOLEAN, &is_playback, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_STRING, &role, + DBUS_TYPE_INVALID)); + + device_string = pa_device_manager_get_device_string(dm, is_playback, type, role); + if (device_string == NULL) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); + return; + } + + pa_log_info("device string : %s", device_string); + pa_assert_se((reply = dbus_message_new_method_return(msg))); + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &device_string, + DBUS_TYPE_INVALID)); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_dump_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + pa_tz_device *device; + uint32_t device_idx; + DBusMessage *reply = NULL; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *) userdata; + + PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { + pa_tz_device_dump_info(device, PA_LOG_INFO); + } + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static bool is_usb_output_device(pa_tz_device *device) { + char *type; + dm_device_direction_t direction; + pa_sink *sink; + + pa_assert(device); + + type = pa_tz_device_get_type(device); + if (!pa_streq(type, DEVICE_TYPE_USB_AUDIO)) { + pa_log_error("device(id:%d, %s) is not USB AUDIO type", pa_tz_device_get_id(device), type); + return false; + } + direction = pa_tz_device_get_direction(device); + if (direction & DM_DEVICE_DIRECTION_OUT) { + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("sink is null"); + return false; + } + } else { + pa_log_error("this device is not for output"); + return false; + } + + return true; +} + + +static bool is_supported_sample_format(pa_sample_format_t *supported_sample_formats, pa_sample_format_t sample_format) { + int i; + + pa_assert(supported_sample_formats); + pa_assert(sample_format != PA_SAMPLE_INVALID); + + for (i = 0; supported_sample_formats[i] != PA_SAMPLE_MAX; i++) { + if (supported_sample_formats[i] == sample_format) { + pa_log_info("%s is supported", pa_sample_format_to_string(sample_format)); + return true; + } + } + pa_log_error("%s is not supported", pa_sample_format_to_string(sample_format)); + return false; +} + +static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + DBusMessageIter msg_iter, array_iter, item_iter; + dbus_int32_t device_id; + pa_tz_device *device; + pa_sink *sink; + const char *format; + int i; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + dm = (pa_device_manager *)userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Get supported sample formats of the device(id:%d)", device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + dbus_message_iter_init_append(reply, &msg_iter); + pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(s)", &array_iter)); + for (i = 0; sink->supported_sample_formats[i] != PA_SAMPLE_MAX; i++) { + format = pa_sample_format_to_string(sink->supported_sample_formats[i]); + pa_log_info("%s is supported", format); + pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &item_iter)); + dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING, &format); + pa_assert_se(dbus_message_iter_close_container(&array_iter, &item_iter)); + } + pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + char *sample_format; + pa_sample_format_t prev_selected_sample_format; + pa_tz_device *device; + pa_sink *sink; + pa_sample_spec spec; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *)userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_STRING, &sample_format, + DBUS_TYPE_INVALID)); + + pa_log_info("Set sample format(%s) of the device(id:%d)", sample_format, device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + /* use a supported sample format selected by user */ + if (!is_supported_sample_format(sink->supported_sample_formats, pa_parse_sample_format(sample_format))) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + prev_selected_sample_format = sink->selected_sample_format; + sink->selected_sample_format = pa_parse_sample_format(sample_format); + + FILL_SAMPLE_SPEC_WITH_SELECTED(spec, sink); + if (pa_sink_reconfigure(sink, &spec, false) == -1) { + pa_log_error("failed to reconfigure"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); + sink->selected_sample_format = prev_selected_sample_format; + return; + } + + save_preference(dm, sink); + + pa_log_info("Set sample format(%s) of the device(id:%d) successfully", sample_format, device_id); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + pa_tz_device *device; + pa_sink *sink; + const char *format; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + dm = (pa_device_manager *)userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Get sample format of the device(id:%d)", device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + format = pa_sample_format_to_string(sink->selected_sample_format); + pa_log_info("Get sample format(%s) of the device(id:%d) successfully", format, device_id); + pa_assert_se((reply = dbus_message_new_method_return(msg))); + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &format, DBUS_TYPE_INVALID)); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static bool is_supported_sample_rate(uint32_t *supported_sample_rates, uint32_t sample_rate) { + int i; + + pa_assert(supported_sample_rates); + + for (i = 0; supported_sample_rates[i]; i++) { + if (supported_sample_rates[i] == sample_rate) { + pa_log_info("%u is supported", sample_rate); + return true; + } + } + pa_log_error("%u is not supported", sample_rate); + return false; +} + +static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + DBusMessageIter msg_iter, array_iter, item_iter; + dbus_int32_t device_id; + pa_tz_device *device; + pa_sink *sink; + int i; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + dm = (pa_device_manager *)userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Get supported sample rates of the device(id:%d)", device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + dbus_message_iter_init_append(reply, &msg_iter); + pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(u)", &array_iter)); + for (i = 0; sink->supported_sample_rates[i]; i++) { + pa_log_info("%u is supported", sink->supported_sample_rates[i]); + pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &item_iter)); + dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_UINT32, &sink->supported_sample_rates[i]); + pa_assert_se(dbus_message_iter_close_container(&array_iter, &item_iter)); + } + pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_set_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + dbus_uint32_t sample_rate; + uint32_t prev_selected_sample_rate; + pa_tz_device *device; + pa_sink *sink; + pa_sample_spec spec; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *)userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_UINT32, &sample_rate, + DBUS_TYPE_INVALID)); + + pa_log_info("Set sample rate(%u) of the device(id:%d)", sample_rate, device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + /* use a supported sample rate selected by user */ + if (!is_supported_sample_rate(sink->supported_sample_rates, sample_rate)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + prev_selected_sample_rate = sink->selected_sample_rate; + sink->selected_sample_rate = sample_rate; + + FILL_SAMPLE_SPEC_WITH_SELECTED(spec, sink); + if (pa_sink_reconfigure(sink, &spec, false) == -1) { + pa_log_error("failed to reconfigure"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); + sink->selected_sample_rate = prev_selected_sample_rate; + return; + } + + save_preference(dm, sink); + + pa_log_info("Set sample rate(%u) of the device(id:%d) successfully", sample_rate, device_id); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + pa_tz_device *device; + pa_sink *sink; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + dm = (pa_device_manager *)userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Get sample rate of the device(id:%d)", device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + pa_log_info("Get sample rate(%u) of the device(id:%d) successfully", sink->selected_sample_rate, device_id); + pa_assert_se((reply = dbus_message_new_method_return(msg))); + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &sink->selected_sample_rate, DBUS_TYPE_INVALID)); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + char *stream_role; + pa_tz_device *device; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *)userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_STRING, &stream_role, + DBUS_TYPE_INVALID)); + + pa_log_info("Set the device(id:%d) only for the stream role(%s)", device_id, stream_role); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!pa_stream_manager_is_valid_stream_role(dm->core, stream_role)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + device->specified_stream_role = stream_role; + + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_get_specified_stream(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + char *specified_stream_role; + pa_tz_device *device; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + dm = (pa_device_manager *)userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Get specified stream role for the device(id:%d)", device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + + specified_stream_role = device->specified_stream_role; + + pa_log_info("stream role(%s) is specified for the device(id:%d)", device->specified_stream_role, device_id); + pa_assert_se((reply = dbus_message_new_method_return(msg))); + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &specified_stream_role, DBUS_TYPE_INVALID)); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_set_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + dbus_bool_t avoid_resampling; + pa_tz_device *device; + pa_sink *sink; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + dm = (pa_device_manager *)userdata; + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_BOOLEAN, &avoid_resampling, + DBUS_TYPE_INVALID)); + + pa_log_info("Set the device(id:%d) avoid-resampling(%d)", device_id, avoid_resampling); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (sink->avoid_resampling == avoid_resampling) { + pa_log_info("already set to %d", avoid_resampling); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); + return; + } + + sink->avoid_resampling = avoid_resampling; + + save_preference(dm, sink); + + pa_log_info("Set avoid-resampling(%d) to the device(id:%d)", avoid_resampling, device_id); + + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_get_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm; + DBusMessage *reply = NULL; + dbus_int32_t device_id; + dbus_bool_t avoid_resampling; + pa_tz_device *device; + pa_sink *sink; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + dm = (pa_device_manager *)userdata; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Get avoid-resampling of the device(id:%d)", device_id); + + if (!(device = device_list_get_device_by_id(dm, device_id))) { + pa_log_error("could not find any device with id:%d", device_id); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + if (!is_usb_output_device(device)) { + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + return; + } + if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { + pa_log_error("could not get sink for normal role"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + return; + } + + avoid_resampling = sink->avoid_resampling; + pa_log_info("got avoid-resampling(%d) of the device(id:%d)", avoid_resampling, device_id); + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &avoid_resampling, DBUS_TYPE_INVALID)); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata) { + pa_device_manager *dm = (pa_device_manager *)userdata; + char *type; + dbus_int32_t status; + DBusMessage *reply = NULL; + DBusError error; + + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + dbus_error_init(&error); + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &type, + DBUS_TYPE_INT32, &status, + DBUS_TYPE_INVALID)) { + pa_log_error("failed to get dbus args : %s", error.message); + pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); + dbus_error_free(&error); + } + + pa_log_debug("handle_test_device_status_change, type:%s, status:%d", type, status); + + handle_device_status_changed(dm, type, NULL, NULL, status); + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); +} + +static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata) { + const char *xml = DEVICE_MANAGER_INTROSPECT_XML; + DBusMessage *r = NULL; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + pa_assert_se(r = dbus_message_new_method_return(msg)); + pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)); + + if (r) { + pa_assert_se(dbus_connection_send((conn), r, NULL)); + dbus_message_unref(r); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult handle_device_manager_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) { + int method_idx = 0; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + for (method_idx = 0; method_idx < METHOD_HANDLER_MAX; method_idx++) { + if (dbus_message_is_method_call(msg, DBUS_INTERFACE_DEVICE_MANAGER, method_handlers[method_idx].method_name)) { + method_handlers[method_idx].receive_cb(conn, msg, userdata); + return DBUS_HANDLER_RESULT_HANDLED; + } + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult method_call_handler(DBusConnection *c, DBusMessage *m, void *userdata) { + struct userdata *u = userdata; + const char *path, *interface, *member; + + pa_assert(c); + pa_assert(m); + pa_assert(u); + + path = dbus_message_get_path(m); + interface = dbus_message_get_interface(m); + member = dbus_message_get_member(m); + + pa_log_info("DeviceManager Method Call Handler : path=%s, interface=%s, member=%s", path, interface, member); + + if (!pa_streq(path, DBUS_OBJECT_DEVICE_MANAGER)) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { + return handle_introspect(c, m, u); + /* + } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Get")) { + return handle_get_property(c, m, u); + } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set")) { + return handle_set_property(c, m, u); + } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "GetAll")) { + return handle_get_all_property(c, m, u); + */ + } else { + return handle_device_manager_methods(c, m, u); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static void fill_signal_msg_with_device(const char *description, DBusMessageIter *msg_iter, uint32_t event_id, pa_tz_device *device) { + DBusMessageIter array_iter, device_iter; + char *type, *name; + dbus_int32_t device_id, direction, state, stream_id; + dbus_int32_t vendor_id, product_id; + dbus_bool_t is_running; + pa_intset *stream_id_set = NULL; + int32_t stream_id_val; + int ret; + + pa_assert(msg_iter); + pa_assert(device); + + dbus_message_iter_append_basic(msg_iter, DBUS_TYPE_UINT32, &event_id); + pa_assert_se(dbus_message_iter_open_container(msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); + + direction = (dbus_int32_t)pa_tz_device_get_direction(device); + type = pa_tz_device_get_type(device); + name = pa_tz_device_get_name(device); + device_id = (dbus_int32_t)pa_tz_device_get_id(device); + state = pa_tz_device_get_state(device); + vendor_id = (dbus_int32_t)pa_tz_device_get_vendor_id(device); + product_id = (dbus_int32_t)pa_tz_device_get_product_id(device); + is_running = (dbus_bool_t)pa_tz_device_is_running(device); + + simple_device_dump(PA_LOG_INFO, description, device_id, type, name, direction, state); + + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &state); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &vendor_id); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &product_id); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_BOOLEAN, &is_running); + if (state == DM_DEVICE_STATE_ACTIVATED) + stream_id_set = pa_tz_device_get_stream_list(device); + pa_assert_se(dbus_message_iter_open_container(&device_iter, DBUS_TYPE_ARRAY, "i", &array_iter)); + if (state == DM_DEVICE_STATE_ACTIVATED) { + PA_INTSET_FOREACH(stream_id_val, stream_id_set, ret) { + stream_id = stream_id_val; + dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_INT32, &stream_id); + } + } + pa_assert_se(dbus_message_iter_close_container(&device_iter, &array_iter)); + if (stream_id_set) + pa_intset_free(stream_id_set); + pa_assert_se(dbus_message_iter_close_container(msg_iter, &device_iter)); + pa_log_info("end of fill signal msg"); +} + +void send_device_connection_changed_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) { + DBusMessage *signal_msg; + DBusMessageIter msg_iter; + dbus_bool_t _connected = connected; + + pa_assert(device); + pa_assert(dm); + + pa_log_info("Send device connection changed signal, event_id(%u)", event_id); + + pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected")); + dbus_message_iter_init_append(signal_msg, &msg_iter); + fill_signal_msg_with_device(connected ? "[Connected]" : "[Disconnected]", &msg_iter, event_id, device); + + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected); + + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); + + dbus_message_unref(signal_msg); + pa_log_info("end of send device connection changed signal"); +} + +void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *device, int changed_type, pa_device_manager *dm) { + DBusMessage *signal_msg; + DBusMessageIter msg_iter; + const char *changed_prefix[] = {"[State Changed]", "[Direction Changed]", "[Avail-Mode Changed]"}; + + pa_assert(device); + pa_assert(dm); + + pa_log_debug("Send device info changed signal, event_id(%u)", event_id); + + pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceInfoChanged")); + dbus_message_iter_init_append(signal_msg, &msg_iter); + fill_signal_msg_with_device(changed_prefix[changed_type], &msg_iter, event_id, device); + dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &changed_type); + + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); + + dbus_message_unref(signal_msg); +} + +void send_device_state_changed_signal(uint32_t event_id, pa_tz_device *device, bool activated, pa_device_manager *dm) { + DBusMessage *signal_msg; + DBusMessageIter msg_iter; + + pa_assert(device); + pa_assert(dm); + + pa_log_debug("Send device state changed signal, event_id(%u)", event_id); + + pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceStateChanged")); + dbus_message_iter_init_append(signal_msg, &msg_iter); + fill_signal_msg_with_device(activated ? "[Activated]" : "[Deactivated]", &msg_iter, event_id, device); + + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); + + dbus_message_unref(signal_msg); +} + +void send_device_running_changed_signal(uint32_t event_id, pa_tz_device *device, bool is_running, pa_device_manager *dm) { + DBusMessage *signal_msg; + DBusMessageIter msg_iter; + + pa_assert(device); + pa_assert(dm); + + pa_log_debug("Send device running changed signal, event_id(%u)", event_id); + + pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceRunningChanged")); + dbus_message_iter_init_append(signal_msg, &msg_iter); + fill_signal_msg_with_device(is_running ? "[Running]" : "[NotRunning]", &msg_iter, event_id, device); + + pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); + + dbus_message_unref(signal_msg); +} + +static void endpoint_init(pa_device_manager *dm) { + static const DBusObjectPathVTable vtable_endpoint = { + .message_function = method_call_handler, + }; + + pa_log_info("Device manager dbus endpoint init"); + + if (dm && dm->dbus_conn) { + if (!dbus_connection_register_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER, &vtable_endpoint, dm)) + pa_log_error("Failed to register object path"); + } else { + pa_log_error("Cannot get dbus connection to register object path"); + } +} + +static void endpoint_done(pa_device_manager *dm) { + pa_log_info("Device manager dbus endpoint done"); + if (dm && dm->dbus_conn) { + if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER)) + pa_log_error("Failed to unregister object path"); + } else { + pa_log_error("Cannot get dbus connection to unregister object path"); + } +} + +static int watch_signals(pa_device_manager *dm) { + DBusError error; + + pa_assert(dm); + pa_assert(dm->dbus_conn); + + dbus_error_init(&error); + + pa_log_info("Watch Dbus signals"); + + if (!dbus_connection_add_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm, NULL)) { + pa_log_error("Unable to add D-Bus filter : %s: %s", error.name, error.message); + goto fail; + } + + if (pa_dbus_add_matches(pa_dbus_connection_get(dm->dbus_conn), &error, FILTER_DEVICED_SYSNOTI, FILTER_SOUND_SERVER, FILTER_BLUEZ, FILTER_MIRRORING, NULL) < 0) { + pa_log_error("Unable to subscribe to signals: %s: %s", error.name, error.message); + goto fail; + } + return 0; + +fail: + dbus_error_free(&error); + return -1; +} + +static void unwatch_signals(pa_device_manager *dm) { + pa_log_info("Unwatch Dbus signals"); + + pa_assert(dm); + pa_assert(dm->dbus_conn); + + pa_dbus_remove_matches(pa_dbus_connection_get(dm->dbus_conn), FILTER_DEVICED_SYSNOTI, FILTER_SOUND_SERVER, FILTER_BLUEZ, FILTER_MIRRORING, NULL); + dbus_connection_remove_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm); +} + +void init_dm_dbus(pa_device_manager *dm) { + DBusError error; + pa_dbus_connection *connection = NULL; + + pa_assert(dm); + pa_log_info("init Dbus"); + dbus_error_init(&error); + + if (!(connection = pa_dbus_bus_get(dm->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { + if (connection) { + pa_dbus_connection_unref(connection); + } + pa_log_error("Unable to contact D-Bus system bus: %s: %s", error.name, error.message); + goto fail; + } else { + pa_log_info("Got dbus connection"); + } + + dm->dbus_conn = connection; + + if (watch_signals(dm) < 0) + pa_log_error("dbus watch signals failed"); + else + pa_log_debug("dbus ready to get signals"); + + endpoint_init(dm); + +fail: + dbus_error_free(&error); +} + +void deinit_dm_dbus(pa_device_manager *dm) { + pa_assert(dm); + + pa_log_info("deinit Dbus"); + + endpoint_done(dm); + unwatch_signals(dm); + + if (dm->dbus_conn) { + pa_dbus_connection_unref(dm->dbus_conn); + dm->dbus_conn = NULL; + } +} +#endif \ No newline at end of file diff --git a/src/device-manager-priv.h b/src/device-manager-priv.h index 32dc8d2..5b8c4f7 100644 --- a/src/device-manager-priv.h +++ b/src/device-manager-priv.h @@ -30,6 +30,7 @@ #include #include #include +#include "device-manager.h" #include "communicator.h" #include "hal-interface.h" @@ -43,7 +44,7 @@ struct device_file_map pa_idxset *capture; }; -struct pa_device_manager { +struct _device_manager { PA_REFCNT_DECLARE; pa_core *core; @@ -76,4 +77,69 @@ struct pa_device_manager { pa_database *database; }; +/* + Enums for represent values which is defined on other module. + This is needed to identify values which are sent by dbus or vconf. +*/ +typedef enum external_value_earjack_type { + EARJACK_DISCONNECTED = 0, + EARJACK_TYPE_SPK_ONLY = 1, + EARJACK_TYPE_SPK_WITH_MIC = 3, +} external_value_earjack_t; + +typedef enum external_value_forwarding_type { + FORWARDING_DISCONNECTED = 0, + FORWARDING_CONNECTED = 1, +} external_value_mirroring_t; + +typedef enum external_value_hdmi_type { + HDMI_AUDIO_DISCONNECTED = -1, + HDMI_AUDIO_NOT_AVAILABLE = 0, + HDMI_AUDIO_AVAILABLE = 1, +} external_value_hdmi_t; + +typedef enum external_value_bt_sco_type { + BT_SCO_DISCONNECTED = 0, + BT_SCO_CONNECTED = 1, +} external_value_bt_sco_t; + +/* + Enums for represent device detected status (through dbus) + When some device is detected, one of these values should be saved in device_status hashmap. + device_detected_type_t is needed to distinguish detected device-types ( ex. earjack which can be out or both way) + So If you just want to know whether detected or not, can device_detected_t as mask. +*/ +typedef enum device_detected_type { + DEVICE_DISCONNECTED = 0x0, + DEVICE_CONNECTED = 0x1, + DEVICE_CONNECTED_AUDIO_JACK_4P = DEVICE_CONNECTED | 0x2, + DEVICE_CONNECTED_AUDIO_JACK_3P = DEVICE_CONNECTED | 0x4, + DEVICE_CONNECTED_SCO = DEVICE_CONNECTED | 0x8, + DEVICE_OPENED_SCO = DEVICE_CONNECTED | 0xF, +} device_detected_type_t; + +typedef enum { + DEVICE_IO_DIRECTION_IN_FLAG = 0x0001, /**< Flag for input devices */ + DEVICE_IO_DIRECTION_OUT_FLAG = 0x0002, /**< Flag for output devices */ + DEVICE_IO_DIRECTION_BOTH_FLAG = 0x0004, /**< Flag for input/output devices (both directions are available) */ + DEVICE_TYPE_INTERNAL_FLAG = 0x0010, /**< Flag for built-in devices */ + DEVICE_TYPE_EXTERNAL_FLAG = 0x0020, /**< Flag for external devices */ + DEVICE_STATE_DEACTIVATED_FLAG = 0x1000, /**< Flag for deactivated devices */ + DEVICE_STATE_ACTIVATED_FLAG = 0x2000, /**< Flag for activated devices */ + DEVICE_ALL_FLAG = 0xFFFF, /**< Flag for all devices */ +} device_flag_t; + +typedef enum { + DEVICE_IO_DIRECTION_FLAGS = 0x000F, /**< Flag for io direction */ + DEVICE_TYPE_FLAGS = 0x00F0, /**< Flag for device type */ + DEVICE_STATE_FLAGS = 0xF000, /**< Flag for device state */ +} device_flags_type_t; + +const char* build_key_from_proplist(pa_proplist *p); +void simple_device_dump(pa_log_level_t level, const char *prefix, int id, const char *type, const char *name, int direction, int state); +void device_set_detected(pa_device_manager *dm, const char *type, const char *name, const char *system_id, device_detected_type_t detected_type); +pa_tz_device *device_list_get_device(pa_device_manager *dm, const char *type, const char *system_id); +pa_tz_device *device_list_get_device_by_id(pa_device_manager *dm, uint32_t id); +void handle_device_connected(pa_device_manager *dm, const char *type, const char *name, const char *system_id, device_detected_type_t detected_type); + #endif diff --git a/src/device-manager.c b/src/device-manager.c index 373c80a..755b7ed 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -45,6 +45,7 @@ #include "stream-manager.h" #include "device-manager.h" #include "device-manager-priv.h" +#include "device-manager-dbus-priv.h" #include "device-manager-db-priv.h" #define SHARED_DEVICE_MANAGER "tizen-device-manager" @@ -81,165 +82,6 @@ #define DEVICE_CLASS_SOUND "sound" #define DEVICE_CLASS_MONITOR "monitor" -/* Dbus defines */ -#define DBUS_INTERFACE_DEVICE_MANAGER "org.pulseaudio.DeviceManager" -#define DBUS_OBJECT_DEVICE_MANAGER "/org/pulseaudio/DeviceManager" - -#define DBUS_INTERFACE_DEVICED_SYSNOTI "org.tizen.system.deviced.SysNoti" -#define DBUS_OBJECT_DEVICED_SYSNOTI "/Org/Tizen/System/DeviceD/SysNoti" - -#define DBUS_INTERFACE_SOUND_SERVER "org.tizen.SoundServer1" -#define DBUS_OBJECT_SOUND_SERVER "/org/tizen/SoundServer1" - -#define DBUS_SERVICE_BLUEZ "org.bluez" -#define DBUS_INTERFACE_BLUEZ_HEADSET "org.bluez.Headset" -#define DBUS_INTERFACE_BLUEZ_DEVICE "org.bluez.Device1" -#define DBUS_OBJECT_BLUEZ "/org/bluez" - -#define DBUS_INTERFACE_MIRRORING_SERVER "org.tizen.scmirroring.server" -#define DBUS_OBJECT_MIRRORING_SERVER "/org/tizen/scmirroring/server" - -#define DBUS_SERVICE_HFP_AGENT "org.bluez.ag_agent" -#define DBUS_OBJECT_HFP_AGENT "/org/bluez/hfp_agent" -#define DBUS_INTERFACE_HFP_AGENT "Org.Hfp.App.Interface" - -#define DEVICE_MANAGER_INTROSPECT_XML \ - DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ - "\n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " " \ - " " \ - " " \ - " " \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - "\n" - -#define FILTER_DEVICED_SYSNOTI \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_DEVICED_SYSNOTI "'" - -#define FILTER_SOUND_SERVER \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_SOUND_SERVER "'" - -#define FILTER_MIRRORING \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_MIRRORING_SERVER "', member='miracast_wfd_source_status_changed'" - -#define FILTER_BLUEZ \ - "type='signal'," \ - " interface='" DBUS_INTERFACE_BLUEZ_HEADSET "', member='PropertyChanged'" - -#define FILL_SAMPLE_SPEC_WITH_SELECTED(x_sink, x_spec) \ -do { \ - x_spec.format = x_sink->selected_sample_format; \ - x_spec.rate = x_sink->selected_sample_rate; \ - x_spec.channels = 2; \ -} while(0) - -#define FILL_SAMPLE_SPEC_WITH_PREFER_ENTRY(x_entry, x_spec) \ -do { \ - x_spec.format = x_entry->format; \ - x_spec.rate = x_entry->rate; \ - x_spec.channels = 2; \ -} while(0) - static const char* const valid_alsa_device_modargs[] = { "name", "sink_name", @@ -274,48 +116,6 @@ static const char* const valid_alsa_device_modargs[] = { #define BT_CVSD_CODEC_ID 1 // narrow-band #define BT_MSBC_CODEC_ID 2 // wide-band -/* - Enums for represent values which is defined on other module. - This is needed to identify values which are sent by dbus or vconf. -*/ -typedef enum external_value_earjack_type { - EARJACK_DISCONNECTED = 0, - EARJACK_TYPE_SPK_ONLY = 1, - EARJACK_TYPE_SPK_WITH_MIC = 3, -} external_value_earjack_t; - -typedef enum external_value_bt_sco_type { - BT_SCO_DISCONNECTED = 0, - BT_SCO_CONNECTED = 1, -} external_value_bt_sco_t; - -typedef enum external_value_forwarding_type { - FORWARDING_DISCONNECTED = 0, - FORWARDING_CONNECTED = 1, -} external_value_mirroring_t; - -typedef enum external_value_hdmi_type { - HDMI_AUDIO_DISCONNECTED = -1, - HDMI_AUDIO_NOT_AVAILABLE = 0, - HDMI_AUDIO_AVAILABLE = 1, -} external_value_hdmi_t; - - -/* - Enums for represent device detected status (through dbus) - When some device is detected, one of these values should be saved in device_status hashmap. - device_detected_type_t is needed to distinguish detected device-types ( ex. earjack which can be out or both way) - So If you just want to know whether detected or not, can device_detected_t as mask. -*/ - -typedef enum device_detected_type { - DEVICE_DISCONNECTED = 0x0, - DEVICE_CONNECTED = 0x1, - DEVICE_CONNECTED_AUDIO_JACK_4P = DEVICE_CONNECTED | 0x2, - DEVICE_CONNECTED_AUDIO_JACK_3P = DEVICE_CONNECTED | 0x4, - DEVICE_CONNECTED_SCO = DEVICE_CONNECTED | 0x8, - DEVICE_OPENED_SCO = DEVICE_CONNECTED | 0xF, -} device_detected_type_t; typedef enum dm_device_class_type { DM_DEVICE_CLASS_NONE, @@ -326,23 +126,6 @@ typedef enum dm_device_class_type { DM_DEVICE_CLASS_MAX, } dm_device_class_t; -typedef enum { - DEVICE_IO_DIRECTION_IN_FLAG = 0x0001, /**< Flag for input devices */ - DEVICE_IO_DIRECTION_OUT_FLAG = 0x0002, /**< Flag for output devices */ - DEVICE_IO_DIRECTION_BOTH_FLAG = 0x0004, /**< Flag for input/output devices (both directions are available) */ - DEVICE_TYPE_INTERNAL_FLAG = 0x0010, /**< Flag for built-in devices */ - DEVICE_TYPE_EXTERNAL_FLAG = 0x0020, /**< Flag for external devices */ - DEVICE_STATE_DEACTIVATED_FLAG = 0x1000, /**< Flag for deactivated devices */ - DEVICE_STATE_ACTIVATED_FLAG = 0x2000, /**< Flag for activated devices */ - DEVICE_ALL_FLAG = 0xFFFF, /**< Flag for all devices */ -} device_flag_t; - -typedef enum { - DEVICE_IO_DIRECTION_FLAGS = 0x000F, /**< Flag for io direction */ - DEVICE_TYPE_FLAGS = 0x00F0, /**< Flag for device type */ - DEVICE_STATE_FLAGS = 0xF000, /**< Flag for device state */ -} device_flags_type_t; - typedef enum dm_device_bt_mode_type { DM_DEVICE_BT_MODE_MEDIA = 0x1, DM_DEVICE_BT_MODE_VOICE = 0x2 @@ -411,122 +194,6 @@ struct composite_type { const char *role; }; -#ifdef HAVE_DBUS - -/*** Defines for method handle ***/ -/* method handlers */ -static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_device_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_specified_stream(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_set_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_unload_sink(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_unload_sink_with_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_get_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_dump_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata); -static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata); - -static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name); - -enum method_handler_index { - METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST, - METHOD_HANDLER_GET_DEVICE_BY_ID, - METHOD_HANDLER_IS_STREAM_ON_DEVICE, - METHOD_HANDLER_GET_BT_A2DP_STATUS, - METHOD_HANDLER_LOAD_SINK, - METHOD_HANDLER_UNLOAD_SINK, - METHOD_HANDLER_UNLOAD_SINK_WITH_DEVICE_STRING, - METHOD_HANDLER_GET_DEVICE_STRING, - METHOD_HANDLER_GET_SUPPORTED_SAMPLE_FORMATS, - METHOD_HANDLER_SET_SAMPLE_FORMAT, - METHOD_HANDLER_GET_SAMPLE_FORMAT, - METHOD_HANDLER_GET_SUPPORTED_SAMPLE_RATES, - METHOD_HANDLER_SET_SAMPLE_RATE, - METHOD_HANDLER_GET_SAMPLE_RATE, - METHOD_HANDLER_SET_SPECIFIC_STREAM_ONLY, - METHOD_HANDLER_GET_SPECIFIED_STREAM, - METHOD_HANDLER_SET_AVOID_RESAMPLING, - METHOD_HANDLER_GET_AVOID_RESAMPLING, - METHOD_HANDLER_DUMP_DEVICE_LIST, - METHOD_HANDLER_STATUS_TEST, - METHOD_HANDLER_MAX -}; - -static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { - [METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST] = { - .method_name = "GetConnectedDeviceList", - .receive_cb = handle_get_connected_device_list }, - [METHOD_HANDLER_GET_DEVICE_BY_ID] = { - .method_name = "GetDeviceById", - .receive_cb = handle_get_device_by_id }, - [METHOD_HANDLER_IS_STREAM_ON_DEVICE] = { - .method_name = "IsStreamOnDevice", - .receive_cb = handle_is_stream_on_device }, - [METHOD_HANDLER_GET_BT_A2DP_STATUS] = { - .method_name = "GetBTA2DPStatus", - .receive_cb = handle_get_bt_a2dp_status }, - [METHOD_HANDLER_LOAD_SINK] = { - .method_name = "LoadSink", - .receive_cb = handle_load_sink }, - [METHOD_HANDLER_UNLOAD_SINK] = { - .method_name = "UnloadSink", - .receive_cb = handle_unload_sink }, - [METHOD_HANDLER_UNLOAD_SINK_WITH_DEVICE_STRING] = { - .method_name = "UnloadSinkWithDeviceString", - .receive_cb = handle_unload_sink_with_device_string }, - [METHOD_HANDLER_GET_DEVICE_STRING] = { - .method_name = "GetDeviceString", - .receive_cb = handle_get_device_string }, - [METHOD_HANDLER_GET_SUPPORTED_SAMPLE_FORMATS] = { - .method_name = "GetSupportedSampleFormats", - .receive_cb = handle_get_supported_sample_formats }, - [METHOD_HANDLER_SET_SAMPLE_FORMAT] = { - .method_name = "SetSampleFormat", - .receive_cb = handle_set_sample_format }, - [METHOD_HANDLER_GET_SAMPLE_FORMAT] = { - .method_name = "GetSampleFormat", - .receive_cb = handle_get_sample_format }, - [METHOD_HANDLER_GET_SUPPORTED_SAMPLE_RATES] = { - .method_name = "GetSupportedSampleRates", - .receive_cb = handle_get_supported_sample_rates }, - [METHOD_HANDLER_SET_SAMPLE_RATE] = { - .method_name = "SetSampleRate", - .receive_cb = handle_set_sample_rate }, - [METHOD_HANDLER_GET_SAMPLE_RATE] = { - .method_name = "GetSampleRate", - .receive_cb = handle_get_sample_rate }, - [METHOD_HANDLER_SET_SPECIFIC_STREAM_ONLY] = { - .method_name = "SetSpecificStreamOnly", - .receive_cb = handle_set_specific_stream_only }, - [METHOD_HANDLER_GET_SPECIFIED_STREAM] = { - .method_name = "GetSpecifiedStream", - .receive_cb = handle_get_specified_stream }, - [METHOD_HANDLER_SET_AVOID_RESAMPLING] = { - .method_name = "SetAvoidResampling", - .receive_cb = handle_set_avoid_resampling }, - [METHOD_HANDLER_GET_AVOID_RESAMPLING] = { - .method_name = "GetAvoidResampling", - .receive_cb = handle_get_avoid_resampling }, - [METHOD_HANDLER_DUMP_DEVICE_LIST] = { - .method_name = "DumpDeviceList", - .receive_cb = handle_dump_device_list }, - [METHOD_HANDLER_STATUS_TEST] = { - .method_name = "TestStatusChange", - .receive_cb = handle_test_device_status_change }, -}; - -#endif - enum internal_codec_device_index { DEVICE_INDEX_BUILTIN_SPEAKER, DEVICE_INDEX_BUILTIN_RECEIVER, @@ -564,6 +231,30 @@ static internal_codec_device internal_codec_devices[DEVICE_INDEX_MAX] = { .is_running[1] = false }, }; +void simple_device_dump(pa_log_level_t level, const char *prefix, int id, const char *type, const char *name, int direction, int state) { + pa_logl(level, "%s device id(%d) type(%s) name (%s) direction(%d) state(%d)", + pa_strempty(prefix), id, pa_strnull(type), pa_strnull(name), direction, state); +} + +const char* build_key_from_proplist(pa_proplist *p) { + const char *vendor_id; + const char *product_id; + static char key[DEVICE_KEY_STR_MAX] = {0,}; + + pa_assert(p); + + vendor_id = pa_proplist_gets(p, PA_PROP_DEVICE_VENDOR_ID); + product_id = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_ID); + if (!vendor_id || !product_id) { + pa_log_error("could not get vendor id(%s) or product id(%s)", vendor_id, product_id); + return NULL; + } + + snprintf(key, DEVICE_KEY_STR_MAX, "%s.%s", vendor_id, product_id); + + return key; +} + static inline void internal_codec_devices_dump() { uint32_t i; pa_log_info("========== devices using internal codec =========="); @@ -573,11 +264,6 @@ static inline void internal_codec_devices_dump() { pa_log_info("=================================================="); } -static inline void simple_device_dump(pa_log_level_t level, const char *prefix, int id, const char *type, const char *name, int direction, int state) { - pa_logl(level, "%s device id(%d) type(%s) name (%s) direction(%d) state(%d)", - pa_strempty(prefix), id, pa_strnull(type), pa_strnull(name), direction, state); -} - static void find_device_and_set_running(pa_device_manager *dm, const char *type, bool is_running) { pa_tz_device* device; @@ -1054,7 +740,7 @@ static device_detected_type_t _device_get_detected(pa_device_manager *manager, c return status_info->detected; } -static void _device_set_detected(pa_device_manager *manager, const char *type, +void device_set_detected(pa_device_manager *manager, const char *type, const char *name, const char *system_id, device_detected_type_t detected_type) { struct device_status_info *status_info; @@ -1085,7 +771,7 @@ static void _device_set_detected(pa_device_manager *manager, const char *type, } } -static pa_tz_device* _device_list_get_device(pa_device_manager *manager, const char *type, const char *system_id) { +pa_tz_device* device_list_get_device(pa_device_manager *manager, const char *type, const char *system_id) { pa_tz_device *device; uint32_t idx; char *_type, *_system_id; @@ -1116,8 +802,7 @@ static pa_tz_device* _device_list_get_device(pa_device_manager *manager, const c return NULL; } - -static pa_tz_device* _device_list_get_device_by_id(pa_device_manager *manager, uint32_t id) { +pa_tz_device* device_list_get_device_by_id(pa_device_manager *manager, uint32_t id) { pa_tz_device *device; uint32_t idx; @@ -1591,7 +1276,7 @@ static pa_sink* _device_manager_set_default_sink(pa_device_manager *dm, const c return NULL; } - if (!(device = _device_list_get_device(dm, type, NULL))) { + if (!(device = device_list_get_device(dm, type, NULL))) { pa_log_warn("cannot get device item for %s", type); return NULL; } @@ -1614,7 +1299,7 @@ static pa_source* _device_manager_set_default_source(pa_device_manager *dm, con return NULL; } - if (!(device = _device_list_get_device(dm, type, NULL))) { + if (!(device = device_list_get_device(dm, type, NULL))) { pa_log_warn("cannot get device item for %s", type); return NULL; } @@ -1628,25 +1313,6 @@ static pa_source* _device_manager_set_default_source(pa_device_manager *dm, con return source; } -static const char* build_key_from_proplist(pa_proplist *p) { - const char *vendor_id; - const char *product_id; - static char key[DEVICE_KEY_STR_MAX] = {0,}; - - pa_assert(p); - - vendor_id = pa_proplist_gets(p, PA_PROP_DEVICE_VENDOR_ID); - product_id = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_ID); - if (!vendor_id || !product_id) { - pa_log_error("could not get vendor id(%s) or product id(%s)", vendor_id, product_id); - return NULL; - } - - snprintf(key, DEVICE_KEY_STR_MAX, "%s.%s", vendor_id, product_id); - - return key; -} - static void apply_preference(pa_device_manager *dm, pa_sink *sink) { const char *key; prefer_entry *e; @@ -1676,7 +1342,7 @@ static void apply_preference(pa_device_manager *dm, pa_sink *sink) { if (do_reconfigure) { pa_sample_spec spec; - FILL_SAMPLE_SPEC_WITH_PREFER_ENTRY(e, spec); + FILL_SAMPLE_SPEC_WITH_PREFER_ENTRY(spec, e); pa_log_info("reconfigure this sink to avoid-resampling(%d), format(%s), rate(%d)", sink->avoid_resampling, pa_sample_format_to_string(e->format), e->rate); pa_sink_reconfigure(sink, &spec, false); @@ -1685,20 +1351,6 @@ static void apply_preference(pa_device_manager *dm, pa_sink *sink) { pa_xfree(e); } -static void save_preference(pa_device_manager *dm, pa_sink *sink) { - const char *key; - prefer_entry e; - - pa_assert(dm); - pa_assert(sink); - - e.avoid_resampling = sink->avoid_resampling; - e.format = sink->selected_sample_format; - e.rate = sink->selected_sample_rate; - if ((key = build_key_from_proplist(sink->proplist))) - write_prefer_entry(dm, key, &e); -} - static void handle_usb_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *dm) { const char *name, *system_id; dm_device_direction_t direction; @@ -1743,7 +1395,7 @@ static void handle_usb_pulse_device(pa_object *pdevice, bool is_loaded, pa_devic pa_tz_device_new(&data); pa_tz_device_new_data_done(&data); } else { - if (!(device = _device_list_get_device(dm, DEVICE_TYPE_USB_AUDIO, system_id))) + if (!(device = device_list_get_device(dm, DEVICE_TYPE_USB_AUDIO, system_id))) pa_log_warn("Can't get usb device for %s", system_id); else pa_tz_device_free(device); @@ -1785,7 +1437,7 @@ static void handle_bt_pulse_device(pa_object *pdevice, bool is_loaded, pa_device pa_tz_device_new_data_done(&data); } else { - if (!(device = _device_list_get_device(dm, DEVICE_TYPE_BT_A2DP, system_id))) + if (!(device = device_list_get_device(dm, DEVICE_TYPE_BT_A2DP, system_id))) pa_log_warn("Can't get bt device for %s", system_id); else pa_tz_device_free(device); @@ -1815,7 +1467,7 @@ static void handle_internal_pulse_device(pa_object *pdevice, bool is_loaded, pa_ for (int i = 0; i < pa_dynarray_size(ctypes); i++) { ctype = pa_dynarray_get(ctypes, i); pa_log_info("Found belongs type %s %s", ctype->type, ctype->role); - if ((device = _device_list_get_device(dm, ctype->type, NULL))) { + if ((device = device_list_get_device(dm, ctype->type, NULL))) { pa_log_info("Add this pulse_device to device(%u)", pa_tz_device_get_id(device)); if (direction == DM_DEVICE_DIRECTION_OUT) pa_tz_device_add_sink(device, ctype->role, PA_SINK(pdevice)); @@ -1830,7 +1482,7 @@ static void handle_internal_pulse_device(pa_object *pdevice, bool is_loaded, pa_ for (int i = 0; i < pa_dynarray_size(ctypes); i++) { ctype = pa_dynarray_get(ctypes, i); pa_log_info("Found belongs type %s %s", ctype->type, ctype->role); - if ((device = _device_list_get_device(dm, ctype->type, NULL))) { + if ((device = device_list_get_device(dm, ctype->type, NULL))) { pa_log_info("Remove this pulse_device from device(%u)", pa_tz_device_get_id(device)); if (direction == DM_DEVICE_DIRECTION_OUT) pa_tz_device_remove_sink(device, PA_SINK(pdevice)); @@ -2136,12 +1788,12 @@ static pa_tz_device* _load_forwarding_device(pa_device_manager *dm) { pa_log_info("Load forwarding device"); - if ((forwarding_device = _device_list_get_device(dm, DEVICE_TYPE_FORWARDING, NULL))) { + if ((forwarding_device = device_list_get_device(dm, DEVICE_TYPE_FORWARDING, NULL))) { pa_log_info("Forwarding device already exists"); return forwarding_device; } - if ((spk_device = _device_list_get_device(dm, DEVICE_TYPE_SPEAKER, NULL)) == NULL) { + if ((spk_device = device_list_get_device(dm, DEVICE_TYPE_SPEAKER, NULL)) == NULL) { pa_log_error("Get speaker device failed"); return NULL; } @@ -2170,7 +1822,7 @@ static pa_tz_device* _load_forwarding_device(pa_device_manager *dm) { And if correnspondent sink/sources for device_type exist, should make device and notify it. Use [device_type->roles] mappings in sink/source for find proper sink/source. */ -static void handle_device_connected(pa_device_manager *dm, const char *type, +void handle_device_connected(pa_device_manager *dm, const char *type, const char *name, const char *system_id, device_detected_type_t detected_type) { struct device_type_info *type_info; pa_tz_device_new_data data; @@ -2239,31 +1891,6 @@ static void handle_device_connected(pa_device_manager *dm, const char *type, return ; } -/* - Handle device disconnection detected through dbus. - First, update device-status hashmap. - And if there is device which has the device_type, remove it. -*/ -static int handle_device_disconnected(pa_device_manager *dm, const char *type, const char *system_id) { - pa_tz_device *device; - - pa_assert(dm); - pa_assert(dm->device_status); - - pa_log_info("Device type(%s) system_id(%s) disconnected", - type, pa_strempty(system_id)); - - device = _device_list_get_device(dm, type, system_id); - if (!device) { - pa_log_error("Disconnection detected but no device for that"); - return -1; - } - - pa_tz_device_free(device); - - return 0; -} - static int load_builtin_devices(pa_device_manager *dm) { struct device_type_info *type_info; uint32_t type_idx; @@ -2486,7 +2113,6 @@ static struct device_file_map *parse_device_file_map() { return file_map; } - static pa_hashmap* parse_device_role_map(json_object *device_role_map_o) { pa_hashmap *roles = NULL; const char *device_string, *device_role; @@ -2531,8 +2157,6 @@ fail: return NULL; } - - static pa_idxset* parse_device_type_infos() { json_object *o, *device_array_o = NULL; int device_type_num = 0; @@ -2597,40 +2221,6 @@ fail: } /* - look detected status which is external value, make conversion to internal consistent value, and handle it - device_type, which type of device is detected - system_id : system_id among same device types for support multi-device -*/ -static int handle_device_status_changed(pa_device_manager *dm, const char *type, - const char *name, const char *system_id, device_detected_type_t detected) { - pa_assert(dm); - - pa_log_info("Device Status Changed, type(%s) system_id(%s), detected_type(%d)", - type, pa_strempty(system_id), detected); - - if (!device_type_is_valid(type)) { - pa_log_error("Invalid device type %s", type); - return -1; - } else if (device_type_is_equal(type, DEVICE_TYPE_BT_SCO)) { - _device_set_detected(dm, type, name, system_id, detected); - if (detected == DEVICE_DISCONNECTED) - handle_device_disconnected(dm, type, system_id); - else - handle_device_connected(dm, type, name, system_id, detected); - } else if (device_type_is_need_detect(type)) { - _device_set_detected(dm, type, name, system_id, detected); - if (detected == DEVICE_DISCONNECTED) - handle_device_disconnected(dm, type, system_id); - else - handle_device_connected(dm, type, name, system_id, detected); - } else { - pa_log_debug("No need to detect type %s", type); - } - - return 0; -} - -/* Initialize device-status idxset. This is for device-status detected through dbus. So, if device_type is not detected through dbus, let's initialize them to detected. (ex. spk, rcv,...) @@ -2655,17 +2245,17 @@ static void device_type_status_init(pa_device_manager *manager) { continue; } if (earjack_status == EARJACK_TYPE_SPK_ONLY) - _device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED_AUDIO_JACK_3P); + device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED_AUDIO_JACK_3P); else if (earjack_status == EARJACK_TYPE_SPK_WITH_MIC) - _device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED_AUDIO_JACK_4P); + device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED_AUDIO_JACK_4P); else if (earjack_status == EARJACK_DISCONNECTED) - _device_set_detected(manager, type, NULL, NULL, DEVICE_DISCONNECTED); + device_set_detected(manager, type, NULL, NULL, DEVICE_DISCONNECTED); else pa_log_warn("Unknown earjack status : %d", earjack_status); } else if (device_type_is_equal(type, DEVICE_TYPE_BT_SCO)) { - _device_set_detected(manager, type, NULL, NULL, DEVICE_DISCONNECTED); + device_set_detected(manager, type, NULL, NULL, DEVICE_DISCONNECTED); } else if (device_type_is_equal(type, DEVICE_TYPE_HDMI)) { - _device_set_detected(manager, type, NULL, NULL, DEVICE_DISCONNECTED); + device_set_detected(manager, type, NULL, NULL, DEVICE_DISCONNECTED); } else if (device_type_is_equal(type, DEVICE_TYPE_FORWARDING)) { int miracast_wfd_status = 0; if (vconf_get_bool(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &miracast_wfd_status) < 0) { @@ -2673,1468 +2263,14 @@ static void device_type_status_init(pa_device_manager *manager) { continue; } if (miracast_wfd_status == FORWARDING_CONNECTED) - _device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED); + device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED); } else { - _device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED); + device_set_detected(manager, type, NULL, NULL, DEVICE_CONNECTED); } } return ; } -#ifdef HAVE_DBUS - -static int _translate_external_value(const char *type, int value, device_detected_type_t *detected) { - - if (!type || !detected) { - pa_log_error("Invalid Parameter for translate"); - return -1; - } - - if (device_type_is_equal(DEVICE_TYPE_AUDIO_JACK, type)) { - if (value == EARJACK_DISCONNECTED) - *detected = DEVICE_DISCONNECTED; - else if (value == EARJACK_TYPE_SPK_ONLY) - *detected = DEVICE_CONNECTED_AUDIO_JACK_3P; - else if (value == EARJACK_TYPE_SPK_WITH_MIC) - *detected = DEVICE_CONNECTED_AUDIO_JACK_4P; - else - return -1; - } else if (device_type_is_equal(DEVICE_TYPE_HDMI, type)) { - if (value == HDMI_AUDIO_DISCONNECTED) - *detected = DEVICE_DISCONNECTED; - else if (value == HDMI_AUDIO_AVAILABLE) - *detected = DEVICE_CONNECTED; - else - return -1; - } else if (device_type_is_equal(DEVICE_TYPE_FORWARDING, type)) { - if (value == FORWARDING_DISCONNECTED) - *detected = DEVICE_DISCONNECTED; - else if (value == FORWARDING_CONNECTED) - *detected = DEVICE_CONNECTED; - else - return -1; - } else if (device_type_is_equal(DEVICE_TYPE_BT_SCO, type)) { - if (value == BT_SCO_DISCONNECTED) - *detected = DEVICE_DISCONNECTED; - else if (value == BT_SCO_CONNECTED) - *detected = DEVICE_CONNECTED_SCO; - else - return -1; - } - - return 0; -} - -static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DBusMessage *s, void *userdata) { - DBusError error; - int status = 0; - pa_device_manager *dm = (pa_device_manager *) userdata; - device_detected_type_t detected; - - pa_assert(userdata); - - if (dbus_message_get_type(s) != DBUS_MESSAGE_TYPE_SIGNAL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - pa_log_info("Device detect handler : Path(%s) Intf(%s) Member(%s) Signature(%s)", - dbus_message_get_path(s), dbus_message_get_interface(s), dbus_message_get_member(s), dbus_message_get_signature(s)); - - dbus_error_init(&error); - - if (dbus_message_is_signal(s, DBUS_INTERFACE_DEVICED_SYSNOTI, "ChangedEarjack")) { - if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { - goto fail; - } else { - if (_translate_external_value(DEVICE_TYPE_AUDIO_JACK, status, &detected) < 0) { - pa_log_warn("failed to translate audio-jack detected value"); - goto fail; - } - handle_device_status_changed(dm, DEVICE_TYPE_AUDIO_JACK, NULL, NULL, detected); - } - } else if (dbus_message_is_signal(s, DBUS_INTERFACE_DEVICED_SYSNOTI, "ChangedHDMIAudio")) { - if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { - goto fail; - } else { - if (_translate_external_value(DEVICE_TYPE_HDMI, status, &detected) < 0) { - pa_log_warn("failed to translate HDMI detected value"); - goto fail; - } - handle_device_status_changed(dm, DEVICE_TYPE_HDMI, NULL, NULL, detected); - } - } else if (dbus_message_is_signal(s, DBUS_INTERFACE_MIRRORING_SERVER, "miracast_wfd_source_status_changed")) { - if (!dbus_message_get_args(s, NULL, DBUS_TYPE_INT32, &status, DBUS_TYPE_INVALID)) { - goto fail; - } else { - if (_translate_external_value(DEVICE_TYPE_FORWARDING, status, &detected) < 0) { - pa_log_warn("failed to translate forwarding detected value"); - goto fail; - } - handle_device_status_changed(dm, DEVICE_TYPE_FORWARDING, NULL, NULL, detected); - } - } else if (dbus_message_is_signal(s, DBUS_INTERFACE_BLUEZ_HEADSET, "PropertyChanged")) { - DBusMessageIter msg_iter, variant_iter; - char *property_name; - - pa_log_debug("Got %s PropertyChanged signal", DBUS_INTERFACE_BLUEZ_HEADSET); - dbus_message_iter_init(s, &msg_iter); - if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_STRING) { - pa_log_error("Property name not string"); - goto fail; - } - dbus_message_iter_get_basic(&msg_iter, &property_name); - pa_log_info("Changed Property name : %s", property_name); - - if (!dbus_message_iter_next(&msg_iter)) { - pa_log_debug("Property value missing"); - goto fail; - } - - if (dbus_message_iter_get_arg_type(&msg_iter) != DBUS_TYPE_VARIANT) { - pa_log_debug("Property value not a variant."); - goto fail; - } - - dbus_message_iter_recurse(&msg_iter, &variant_iter); - - if (DBUS_TYPE_BOOLEAN == dbus_message_iter_get_arg_type(&variant_iter)) { - dbus_bool_t value; - char *name = NULL; - dbus_message_iter_get_basic(&variant_iter, &value); - if (pa_streq(property_name, "Connected")) { - pa_log_info("HFP Connection : %d", value); - if (value) { - method_call_bt_get_name(c, dbus_message_get_path(s), &name); - status = BT_SCO_CONNECTED; - } else { - status = BT_SCO_DISCONNECTED; - } - if (_translate_external_value(DEVICE_TYPE_BT_SCO, status, &detected) < 0) { - pa_log_warn("failed to translate bt-sco detected value"); - goto fail; - } - handle_device_status_changed(dm, DEVICE_TYPE_BT_SCO, - name, dbus_message_get_path(s), detected); - } else if (pa_streq(property_name, "Playing")) { - pa_tz_device *device; - pa_log_info("SCO Playing : %d", value); - if ((device = _device_list_get_device(dm, DEVICE_TYPE_BT_SCO, NULL)) != NULL) { - device->sco_opened = value; - if (value) { - /* update BT band/nrec information */ - bool is_wide_band = false; - bool nrec = false; - pa_tz_device_sco_get_property(device, &is_wide_band, &nrec); - pa_log_info("got new wideband:%d, nrec:%d", is_wide_band, nrec); - - UPDATE_HAL_ROUTE_OPTION(dm->hal_interface, NULL, "bt-wideband", is_wide_band); - UPDATE_HAL_ROUTE_OPTION(dm->hal_interface, NULL, "bt-nrec", nrec); - } - } - UPDATE_HAL_ROUTE_OPTION(dm->hal_interface, NULL, "bt-sco-ready", value); - } - } - } else { - pa_log_debug("Unknown message, not handle it"); - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - pa_log_debug("Dbus Message handled"); - - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_HANDLED; - -fail: - pa_log_error("Fail to handle dbus signal"); - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static int watch_signals(pa_device_manager *dm) { - DBusError error; - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - dbus_error_init(&error); - - pa_log_info("Watch Dbus signals"); - - if (!dbus_connection_add_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm, NULL)) { - pa_log_error("Unable to add D-Bus filter : %s: %s", error.name, error.message); - goto fail; - } - - if (pa_dbus_add_matches(pa_dbus_connection_get(dm->dbus_conn), &error, FILTER_DEVICED_SYSNOTI, FILTER_SOUND_SERVER, FILTER_BLUEZ, FILTER_MIRRORING, NULL) < 0) { - pa_log_error("Unable to subscribe to signals: %s: %s", error.name, error.message); - goto fail; - } - return 0; - -fail: - dbus_error_free(&error); - return -1; -} - -static void unwatch_signals(pa_device_manager *dm) { - pa_log_info("Unwatch Dbus signals"); - - pa_assert(dm); - pa_assert(dm->dbus_conn); - - pa_dbus_remove_matches(pa_dbus_connection_get(dm->dbus_conn), FILTER_DEVICED_SYSNOTI, FILTER_SOUND_SERVER, FILTER_BLUEZ, FILTER_MIRRORING, NULL); - dbus_connection_remove_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm); -} - -static void fill_signal_msg_with_device(const char *description, DBusMessageIter *msg_iter, uint32_t event_id, pa_tz_device *device) { - DBusMessageIter array_iter, device_iter; - char *type, *name; - dbus_int32_t device_id, direction, state, stream_id; - dbus_int32_t vendor_id, product_id; - dbus_bool_t is_running; - pa_intset *stream_id_set = NULL; - int32_t stream_id_val; - int ret; - - pa_assert(msg_iter); - pa_assert(device); - - dbus_message_iter_append_basic(msg_iter, DBUS_TYPE_UINT32, &event_id); - pa_assert_se(dbus_message_iter_open_container(msg_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); - - direction = (dbus_int32_t) pa_tz_device_get_direction(device); - type = pa_tz_device_get_type(device); - name = pa_tz_device_get_name(device); - device_id = (dbus_int32_t) pa_tz_device_get_id(device); - state = pa_tz_device_get_state(device); - vendor_id = (dbus_int32_t) pa_tz_device_get_vendor_id(device); - product_id = (dbus_int32_t) pa_tz_device_get_product_id(device); - is_running = (dbus_bool_t) pa_tz_device_is_running(device); - - simple_device_dump(PA_LOG_INFO, description, device_id, type, name, direction, state); - - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &vendor_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &product_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_BOOLEAN, &is_running); - if (state == DM_DEVICE_STATE_ACTIVATED) - stream_id_set = pa_tz_device_get_stream_list(device); - pa_assert_se(dbus_message_iter_open_container(&device_iter, DBUS_TYPE_ARRAY, "i", &array_iter)); - if (state == DM_DEVICE_STATE_ACTIVATED) { - PA_INTSET_FOREACH(stream_id_val, stream_id_set, ret) { - stream_id = stream_id_val; - dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_INT32, &stream_id); - } - } - pa_assert_se(dbus_message_iter_close_container(&device_iter, &array_iter)); - if (stream_id_set) - pa_intset_free(stream_id_set); - pa_assert_se(dbus_message_iter_close_container(msg_iter, &device_iter)); - pa_log_info("end of fill signal msg"); -} - -static void send_device_connection_changed_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) { - DBusMessage *signal_msg; - DBusMessageIter msg_iter; - dbus_bool_t _connected = connected; - - pa_assert(device); - pa_assert(dm); - - pa_log_info("Send device connection changed signal, event_id(%u)", event_id); - - pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceConnected")); - dbus_message_iter_init_append(signal_msg, &msg_iter); - fill_signal_msg_with_device(connected ? "[Connected]" : "[Disconnected]", &msg_iter, event_id, device); - - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected); - - pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); - - dbus_message_unref(signal_msg); - pa_log_info("end of send device connection changed signal"); -} - -static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *device, int changed_type, pa_device_manager *dm) { - DBusMessage *signal_msg; - DBusMessageIter msg_iter; - const char *changed_prefix[] = {"[State Changed]", "[Direction Changed]", "[Avail-Mode Changed]"}; - - pa_assert(device); - pa_assert(dm); - - pa_log_debug("Send device info changed signal, event_id(%u)", event_id); - - pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceInfoChanged")); - dbus_message_iter_init_append(signal_msg, &msg_iter); - fill_signal_msg_with_device(changed_prefix[changed_type], &msg_iter, event_id, device); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &changed_type); - - pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); - - dbus_message_unref(signal_msg); -} - -static void send_device_state_changed_signal(uint32_t event_id, pa_tz_device *device, bool activated, pa_device_manager *dm) { - DBusMessage *signal_msg; - DBusMessageIter msg_iter; - - pa_assert(device); - pa_assert(dm); - - pa_log_debug("Send device state changed signal, event_id(%u)", event_id); - - pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceStateChanged")); - dbus_message_iter_init_append(signal_msg, &msg_iter); - fill_signal_msg_with_device(activated ? "[Activated]" : "[Deactivated]", &msg_iter, event_id, device); - - pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); - - dbus_message_unref(signal_msg); -} - -static void send_device_running_changed_signal(uint32_t event_id, pa_tz_device *device, bool is_running, pa_device_manager *dm) { - DBusMessage *signal_msg; - DBusMessageIter msg_iter; - - pa_assert(device); - pa_assert(dm); - - pa_log_debug("Send device running changed signal, event_id(%u)", event_id); - - pa_assert_se(signal_msg = dbus_message_new_signal(DBUS_OBJECT_DEVICE_MANAGER, DBUS_INTERFACE_DEVICE_MANAGER, "DeviceRunningChanged")); - dbus_message_iter_init_append(signal_msg, &msg_iter); - fill_signal_msg_with_device(is_running ? "[Running]" : "[NotRunning]", &msg_iter, event_id, device); - - pa_assert_se(dbus_connection_send(pa_dbus_connection_get(dm->dbus_conn), signal_msg, NULL)); - - dbus_message_unref(signal_msg); -} - -static bool device_is_match_direction(pa_tz_device *device, int direction_mask) { - dm_device_direction_t direction; - - if (direction_mask == DEVICE_IO_DIRECTION_FLAGS || direction_mask == 0) - return true; - - direction = pa_tz_device_get_direction(device); - - if ((direction_mask & DEVICE_IO_DIRECTION_IN_FLAG) && (direction & DM_DEVICE_DIRECTION_IN)) - return true; - if ((direction_mask & DEVICE_IO_DIRECTION_OUT_FLAG) && (direction & DM_DEVICE_DIRECTION_OUT)) - return true; - if ((direction_mask & DEVICE_IO_DIRECTION_BOTH_FLAG) && (direction == DM_DEVICE_DIRECTION_BOTH)) - return true; - - return false; -} - -static bool device_is_match_state(pa_tz_device *device, int state_mask) { - dm_device_state_t state; - - if (state_mask == DEVICE_STATE_FLAGS || state_mask == 0) - return true; - - state = pa_tz_device_get_state(device); - - if ((state_mask & DEVICE_STATE_DEACTIVATED_FLAG) && (state == DM_DEVICE_STATE_DEACTIVATED)) - return true; - if ((state_mask & DEVICE_STATE_ACTIVATED_FLAG) && (state == DM_DEVICE_STATE_ACTIVATED)) - return true; - - return false; -} - -static bool device_is_match_type(pa_tz_device *device, int type_mask) { - char *type; - bool is_builtin; - - if (type_mask == DEVICE_TYPE_FLAGS || type_mask == 0) - return true; - - type = pa_tz_device_get_type(device); - is_builtin = device_type_is_builtin(type); - - if ((type_mask & DEVICE_TYPE_INTERNAL_FLAG) && is_builtin) - return true; - if ((type_mask & DEVICE_TYPE_EXTERNAL_FLAG) && !is_builtin) - return true; - - return false; -} - -static bool device_is_match_with_mask(pa_tz_device *device, int mask) { - pa_assert(device); - - if (mask == DEVICE_ALL_FLAG) - return true; - - return (device_is_match_direction(device, mask & DEVICE_IO_DIRECTION_FLAGS) && - device_is_match_state(device, mask & DEVICE_STATE_FLAGS) && - device_is_match_type(device, mask & DEVICE_TYPE_FLAGS)); -} - -static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name) { - const char *intf = DBUS_INTERFACE_BLUEZ_DEVICE, *prop = "Alias"; - DBusMessage *msg, *reply; - DBusMessageIter reply_iter, variant_iter; - DBusError err; - - pa_assert(conn); - pa_assert(device_path); - pa_assert(name); - - if (!(msg = dbus_message_new_method_call(DBUS_SERVICE_BLUEZ, device_path, "org.freedesktop.DBus.Properties", "Get"))) { - pa_log_error("dbus method call failed"); - return -1; - } - - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &intf, - DBUS_TYPE_STRING, &prop, - DBUS_TYPE_INVALID); - - dbus_error_init(&err); - if (!(reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &err))) { - pa_log_error("Failed to method call %s.%s, %s", DBUS_INTERFACE_BLUEZ_DEVICE, "Get", err.message); - dbus_error_free(&err); - return -1; - } - - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_VARIANT) { - pa_log_error("Cannot get reply argument"); - return -1; - } - - dbus_message_iter_recurse(&reply_iter, &variant_iter); - - if (dbus_message_iter_get_arg_type(&variant_iter) == DBUS_TYPE_STRING) { - dbus_message_iter_get_basic(&variant_iter, name); - } - - dbus_message_unref(reply); - return 0; -} - -static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - DBusMessageIter msg_iter, array_iter, device_iter; - pa_tz_device *device; - dm_device_state_t state; - uint32_t device_idx; - dbus_int32_t device_id, direction; - int mask; - char *type, *name; - dbus_int32_t vendor_id, product_id; - dbus_bool_t is_running; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - - dm = (pa_device_manager*) userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &mask, - DBUS_TYPE_INVALID)); - - pa_log_info("Get connected device list (mask : %d)", mask); - - dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiisiib)", &array_iter)); - - PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { - device_id = (dbus_int32_t)pa_tz_device_get_id(device); - state = pa_tz_device_get_state(device); - direction = pa_tz_device_get_direction(device); - type = pa_tz_device_get_type(device); - name = pa_tz_device_get_name(device); - vendor_id = (dbus_int32_t) pa_tz_device_get_vendor_id(device); - product_id = (dbus_int32_t) pa_tz_device_get_product_id(device); - product_id = (dbus_int32_t) pa_tz_device_get_product_id(device); - is_running = (dbus_bool_t) pa_tz_device_is_running(device); - if (device_is_match_with_mask(device, mask)) { - simple_device_dump(PA_LOG_INFO, "[MATCH]", device_id, type, name, direction, state); - pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &device_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &type); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &direction); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &state); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &vendor_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &product_id); - dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_BOOLEAN, &is_running); - pa_assert_se(dbus_message_iter_close_container(&array_iter, &device_iter)); - } else { - simple_device_dump(PA_LOG_INFO, "[UNMATCH]", device_id, type, name, direction, state); - } - } - - pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_get_device_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *manager; - DBusMessage *reply; - DBusMessageIter msg_iter; - pa_tz_device *device; - dbus_int32_t device_id; - dbus_int32_t id, direction, state; - dbus_int32_t vendor_id, product_id; - char *type, *name; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - manager = (pa_device_manager*) userdata; - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - pa_log_info("Get device by id(%d)", device_id); - - if ((device = _device_list_get_device_by_id(manager, device_id))) { - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dbus_message_iter_init_append(reply, &msg_iter); - - id = (dbus_int32_t)pa_tz_device_get_id(device); - state = pa_tz_device_get_state(device); - direction = pa_tz_device_get_direction(device); - type = pa_tz_device_get_type(device); - name = pa_tz_device_get_name(device); - vendor_id = (dbus_int32_t) pa_tz_device_get_vendor_id(device); - product_id = (dbus_int32_t) pa_tz_device_get_product_id(device); - - simple_device_dump(PA_LOG_INFO, "[GET_BY_ID]", device_id, type, name, direction, state); - - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &id); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &type); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &direction); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &state); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_STRING, &name); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &vendor_id); - dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &product_id); - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - } else { - pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); - } -} - -static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *manager; - DBusMessage *reply; - pa_tz_device *device; - dbus_bool_t is_on = false; - dbus_int32_t stream_id, device_id; - pa_intset *stream_id_set; - int32_t stream_id_val; - int ret; - dm_device_state_t state; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_log_info("Is stream on device"); - - manager = (pa_device_manager*) userdata; - - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &stream_id, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - if ((device = _device_list_get_device_by_id(manager, device_id))) { - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - state = pa_tz_device_get_state(device); - if (state == DM_DEVICE_STATE_ACTIVATED) { - stream_id_set = pa_tz_device_get_stream_list(device); - PA_INTSET_FOREACH(stream_id_val, stream_id_set, ret) { - if (stream_id_val == stream_id) { - is_on = true; - pa_log_info("stream(%d) is on device(%d)", stream_id, device_id); - break; - } - } - pa_intset_free(stream_id_set); - } else { - pa_log_info("device(%d) is not activated, regard as no stream on it", device_id); - is_on = false; - } - - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_on, - DBUS_TYPE_INVALID)); - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - } else { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.Internal"); - } -} - -static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - pa_tz_device *device; - dbus_bool_t is_bt_on = false; - const char *bt_name = "none"; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_log_info("Get BT A2DP list"); - - dm = (pa_device_manager*) userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - /* FIXME : Give system_id for multi device */ - if ((device = _device_list_get_device(dm, DEVICE_TYPE_BT_A2DP, NULL)) != NULL) { - is_bt_on = true; - bt_name = pa_tz_device_get_name(device); - } - - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_bt_on, - DBUS_TYPE_STRING, &bt_name, - DBUS_TYPE_INVALID)); - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - - - -static void handle_load_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - char *type, *role; - DBusMessage *reply = NULL; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *) userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_STRING, &role, - DBUS_TYPE_INVALID)); - - pa_device_manager_load_sink(dm, type, role); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_unload_sink(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - char *type, *role; - DBusMessage *reply = NULL; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *) userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_STRING, &role, - DBUS_TYPE_INVALID)); - - pa_device_manager_unload_sink(dm, type, role); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_unload_sink_with_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - char *device_string; - DBusMessage *reply = NULL; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *) userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &device_string, - DBUS_TYPE_INVALID)); - - pa_device_manager_unload_sink_with_device_string(dm, device_string); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_get_device_string(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - char *type, *role; - const char *device_string; - dbus_bool_t is_playback; - DBusMessage *reply; - - dm = (pa_device_manager *) userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_BOOLEAN, &is_playback, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_STRING, &role, - DBUS_TYPE_INVALID)); - - device_string = pa_device_manager_get_device_string(dm, is_playback, type, role); - if (device_string == NULL) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); - return; - } - - pa_log_info("device string : %s", device_string); - pa_assert_se((reply = dbus_message_new_method_return(msg))); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &device_string, - DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_dump_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - pa_tz_device *device; - uint32_t device_idx; - DBusMessage *reply = NULL; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *) userdata; - - PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { - pa_tz_device_dump_info(device, PA_LOG_INFO); - } - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static bool is_usb_output_device(pa_tz_device *device) { - char *type; - dm_device_direction_t direction; - pa_sink *sink; - - pa_assert(device); - - type = pa_tz_device_get_type(device); - if (!pa_streq(type, DEVICE_TYPE_USB_AUDIO)) { - pa_log_error("device(id:%d, %s) is not USB AUDIO type", pa_tz_device_get_id(device), type); - return false; - } - direction = pa_tz_device_get_direction(device); - if (direction & DM_DEVICE_DIRECTION_OUT) { - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("sink is null"); - return false; - } - } else { - pa_log_error("this device is not for output"); - return false; - } - - return true; -} - - -static bool is_supported_sample_format(pa_sample_format_t *supported_sample_formats, pa_sample_format_t sample_format) { - int i; - - pa_assert(supported_sample_formats); - pa_assert(sample_format != PA_SAMPLE_INVALID); - - for (i = 0; supported_sample_formats[i] != PA_SAMPLE_MAX; i++) { - if (supported_sample_formats[i] == sample_format) { - pa_log_info("%s is supported", pa_sample_format_to_string(sample_format)); - return true; - } - } - pa_log_error("%s is not supported", pa_sample_format_to_string(sample_format)); - return false; -} - -static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - DBusMessageIter msg_iter, array_iter, item_iter; - dbus_int32_t device_id; - pa_tz_device *device; - pa_sink *sink; - const char *format; - int i; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - dm = (pa_device_manager *)userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - pa_log_info("Get supported sample formats of the device(id:%d)", device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(s)", &array_iter)); - for (i = 0; sink->supported_sample_formats[i] != PA_SAMPLE_MAX; i++) { - format = pa_sample_format_to_string(sink->supported_sample_formats[i]); - pa_log_info("%s is supported", format); - pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &item_iter)); - dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING, &format); - pa_assert_se(dbus_message_iter_close_container(&array_iter, &item_iter)); - } - pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - char *sample_format; - pa_sample_format_t prev_selected_sample_format; - pa_tz_device *device; - pa_sink *sink; - pa_sample_spec spec; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *)userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_STRING, &sample_format, - DBUS_TYPE_INVALID)); - - pa_log_info("Set sample format(%s) of the device(id:%d)", sample_format, device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - /* use a supported sample format selected by user */ - if (!is_supported_sample_format(sink->supported_sample_formats, pa_parse_sample_format(sample_format))) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - prev_selected_sample_format = sink->selected_sample_format; - sink->selected_sample_format = pa_parse_sample_format(sample_format); - - FILL_SAMPLE_SPEC_WITH_SELECTED(sink, spec); - if (pa_sink_reconfigure(sink, &spec, false) == -1) { - pa_log_error("failed to reconfigure"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); - sink->selected_sample_format = prev_selected_sample_format; - return; - } - - save_preference(dm, sink); - - pa_log_info("Set sample format(%s) of the device(id:%d) successfully", sample_format, device_id); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - pa_tz_device *device; - pa_sink *sink; - const char *format; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - dm = (pa_device_manager *)userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - pa_log_info("Get sample format of the device(id:%d)", device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - format = pa_sample_format_to_string(sink->selected_sample_format); - pa_log_info("Get sample format(%s) of the device(id:%d) successfully", format, device_id); - pa_assert_se((reply = dbus_message_new_method_return(msg))); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &format, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static bool is_supported_sample_rate(uint32_t *supported_sample_rates, uint32_t sample_rate) { - int i; - - pa_assert(supported_sample_rates); - - for (i = 0; supported_sample_rates[i]; i++) { - if (supported_sample_rates[i] == sample_rate) { - pa_log_info("%u is supported", sample_rate); - return true; - } - } - pa_log_error("%u is not supported", sample_rate); - return false; -} - -static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - DBusMessageIter msg_iter, array_iter, item_iter; - dbus_int32_t device_id; - pa_tz_device *device; - pa_sink *sink; - int i; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - dm = (pa_device_manager *)userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - pa_log_info("Get supported sample rates of the device(id:%d)", device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(u)", &array_iter)); - for (i = 0; sink->supported_sample_rates[i]; i++) { - pa_log_info("%u is supported", sink->supported_sample_rates[i]); - pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &item_iter)); - dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_UINT32, &sink->supported_sample_rates[i]); - pa_assert_se(dbus_message_iter_close_container(&array_iter, &item_iter)); - } - pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_set_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - dbus_uint32_t sample_rate; - uint32_t prev_selected_sample_rate; - pa_tz_device *device; - pa_sink *sink; - pa_sample_spec spec; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *)userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_UINT32, &sample_rate, - DBUS_TYPE_INVALID)); - - pa_log_info("Set sample rate(%u) of the device(id:%d)", sample_rate, device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - /* use a supported sample rate selected by user */ - if (!is_supported_sample_rate(sink->supported_sample_rates, sample_rate)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - prev_selected_sample_rate = sink->selected_sample_rate; - sink->selected_sample_rate = sample_rate; - - FILL_SAMPLE_SPEC_WITH_SELECTED(sink, spec); - if (pa_sink_reconfigure(sink, &spec, false) == -1) { - pa_log_error("failed to reconfigure"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); - sink->selected_sample_rate = prev_selected_sample_rate; - return; - } - - save_preference(dm, sink); - - pa_log_info("Set sample rate(%u) of the device(id:%d) successfully", sample_rate, device_id); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - pa_tz_device *device; - pa_sink *sink; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - dm = (pa_device_manager *)userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - pa_log_info("Get sample rate of the device(id:%d)", device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - pa_log_info("Get sample rate(%u) of the device(id:%d) successfully", sink->selected_sample_rate, device_id); - pa_assert_se((reply = dbus_message_new_method_return(msg))); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, &sink->selected_sample_rate, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - char *stream_role; - pa_tz_device *device; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *)userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_STRING, &stream_role, - DBUS_TYPE_INVALID)); - - pa_log_info("Set the device(id:%d) only for the stream role(%s)", device_id, stream_role); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!pa_stream_manager_is_valid_stream_role(dm->core, stream_role)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - device->specified_stream_role = stream_role; - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_get_specified_stream(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - char *specified_stream_role; - pa_tz_device *device; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - dm = (pa_device_manager *)userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - pa_log_info("Get specified stream role for the device(id:%d)", device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - - specified_stream_role = device->specified_stream_role; - - pa_log_info("stream role(%s) is specified for the device(id:%d)", device->specified_stream_role, device_id); - pa_assert_se((reply = dbus_message_new_method_return(msg))); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &specified_stream_role, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_set_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - dbus_bool_t avoid_resampling; - pa_tz_device *device; - pa_sink *sink; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - dm = (pa_device_manager *)userdata; - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_BOOLEAN, &avoid_resampling, - DBUS_TYPE_INVALID)); - - pa_log_info("Set the device(id:%d) avoid-resampling(%d)", device_id, avoid_resampling); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (sink->avoid_resampling == avoid_resampling) { - pa_log_info("already set to %d", avoid_resampling); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); - return; - } - - sink->avoid_resampling = avoid_resampling; - - save_preference(dm, sink); - - pa_log_info("Set avoid-resampling(%d) to the device(id:%d)", avoid_resampling, device_id); - - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_get_avoid_resampling(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm; - DBusMessage *reply = NULL; - dbus_int32_t device_id; - dbus_bool_t avoid_resampling; - pa_tz_device *device; - pa_sink *sink; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - dm = (pa_device_manager *)userdata; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &device_id, - DBUS_TYPE_INVALID)); - - pa_log_info("Get avoid-resampling of the device(id:%d)", device_id); - - if (!(device = _device_list_get_device_by_id(dm, device_id))) { - pa_log_error("could not find any device with id:%d", device_id); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); - return; - } - if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { - pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); - return; - } - - avoid_resampling = sink->avoid_resampling; - pa_log_info("got avoid-resampling(%d) of the device(id:%d)", avoid_resampling, device_id); - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &avoid_resampling, DBUS_TYPE_INVALID)); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata) { - pa_device_manager *dm = (pa_device_manager *)userdata; - char *type; - dbus_int32_t status; - DBusMessage *reply = NULL; - DBusError error; - - pa_assert_se((reply = dbus_message_new_method_return(msg))); - - dbus_error_init(&error); - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &type, - DBUS_TYPE_INT32, &status, - DBUS_TYPE_INVALID)) { - pa_log_error("failed to get dbus args : %s", error.message); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", error.message); - dbus_error_free(&error); - } - - pa_log_debug("handle_test_device_status_change, type:%s, status:%d", type, status); - - handle_device_status_changed(dm, type, NULL, NULL, status); - pa_assert_se(dbus_connection_send(conn, reply, NULL)); - dbus_message_unref(reply); -} - -static DBusHandlerResult handle_introspect(DBusConnection *conn, DBusMessage *msg, void *userdata) { - const char *xml = DEVICE_MANAGER_INTROSPECT_XML; - DBusMessage *r = NULL; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - pa_assert_se(r = dbus_message_new_method_return(msg)); - pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)); - - if (r) { - pa_assert_se(dbus_connection_send((conn), r, NULL)); - dbus_message_unref(r); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusHandlerResult handle_device_manager_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) { - int method_idx = 0; - - pa_assert(conn); - pa_assert(msg); - pa_assert(userdata); - - for (method_idx = 0; method_idx < METHOD_HANDLER_MAX; method_idx++) { - if (dbus_message_is_method_call(msg, DBUS_INTERFACE_DEVICE_MANAGER, method_handlers[method_idx].method_name)) { - method_handlers[method_idx].receive_cb(conn, msg, userdata); - return DBUS_HANDLER_RESULT_HANDLED; - } - } - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -static DBusHandlerResult method_call_handler(DBusConnection *c, DBusMessage *m, void *userdata) { - struct userdata *u = userdata; - const char *path, *interface, *member; - - pa_assert(c); - pa_assert(m); - pa_assert(u); - - path = dbus_message_get_path(m); - interface = dbus_message_get_interface(m); - member = dbus_message_get_member(m); - - pa_log_info("DeviceManager Method Call Handler : path=%s, interface=%s, member=%s", path, interface, member); - - if (!pa_streq(path, DBUS_OBJECT_DEVICE_MANAGER)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { - return handle_introspect(c, m, u); - /* - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Get")) { - return handle_get_property(c, m, u); - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set")) { - return handle_set_property(c, m, u); - } else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "GetAll")) { - return handle_get_all_property(c, m, u); - */ - } else { - return handle_device_manager_methods(c, m, u); - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void endpoint_init(pa_device_manager *dm) { - static const DBusObjectPathVTable vtable_endpoint = { - .message_function = method_call_handler, - }; - - pa_log_info("Device manager dbus endpoint init"); - - if (dm && dm->dbus_conn) { - if (!dbus_connection_register_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER, &vtable_endpoint, dm)) - pa_log_error("Failed to register object path"); - } else { - pa_log_error("Cannot get dbus connection to register object path"); - } -} - -static void endpoint_done(pa_device_manager *dm) { - pa_log_info("Device manager dbus endpoint done"); - if (dm && dm->dbus_conn) { - if (!dbus_connection_unregister_object_path(pa_dbus_connection_get(dm->dbus_conn), DBUS_OBJECT_DEVICE_MANAGER)) - pa_log_error("Failed to unregister object path"); - } else { - pa_log_error("Cannot get dbus connection to unregister object path"); - } -} - -static void init_dbus(pa_device_manager *dm) { - DBusError error; - pa_dbus_connection *connection = NULL; - - pa_assert(dm); - pa_log_info("init Dbus"); - dbus_error_init(&error); - - if (!(connection = pa_dbus_bus_get(dm->core, DBUS_BUS_SYSTEM, &error)) || dbus_error_is_set(&error)) { - if (connection) { - pa_dbus_connection_unref(connection); - } - pa_log_error("Unable to contact D-Bus system bus: %s: %s", error.name, error.message); - goto fail; - } else { - pa_log_info("Got dbus connection"); - } - - dm->dbus_conn = connection; - - if (watch_signals(dm) < 0) - pa_log_error("dbus watch signals failed"); - else - pa_log_debug("dbus ready to get signals"); - - endpoint_init(dm); - -fail: - dbus_error_free(&error); -} - -static void deinit_dbus(pa_device_manager *dm) { - pa_assert(dm); - - pa_log_info("deinit Dbus"); - - endpoint_done(dm); - unwatch_signals(dm); - - if (dm->dbus_conn) { - pa_dbus_connection_unref(dm->dbus_conn); - dm->dbus_conn = NULL; - } -} -#endif - pa_idxset* pa_device_manager_get_device_list(pa_device_manager *dm) { pa_assert(dm); pa_assert(dm->device_list); @@ -4145,13 +2281,13 @@ pa_idxset* pa_device_manager_get_device_list(pa_device_manager *dm) { pa_tz_device* pa_device_manager_get_device(pa_device_manager *dm, const char *type) { pa_assert(dm); - return _device_list_get_device(dm, type, NULL); + return device_list_get_device(dm, type, NULL); } pa_tz_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t id) { pa_assert(dm); - return _device_list_get_device_by_id(dm, id); + return device_list_get_device_by_id(dm, id); } pa_tz_device* pa_device_manager_get_device_with_sink(pa_sink *sink) { @@ -4173,7 +2309,7 @@ pa_tz_device* pa_device_manager_load_forwarding(pa_device_manager *dm) { void pa_device_manager_unload_forwarding(pa_device_manager *dm) { pa_tz_device *forwarding_device; - forwarding_device = _device_list_get_device(dm, DEVICE_TYPE_FORWARDING, NULL); + forwarding_device = device_list_get_device(dm, DEVICE_TYPE_FORWARDING, NULL); if (forwarding_device) pa_tz_device_free(forwarding_device); else @@ -4482,7 +2618,7 @@ pa_device_manager* pa_device_manager_get(pa_core *c) { init_database(dm); - init_dbus(dm); + init_dm_dbus(dm); dm->sink_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, dm); dm->sink_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, dm); @@ -4587,7 +2723,7 @@ void pa_device_manager_unref(pa_device_manager *dm) { if (dm->device_status) pa_idxset_free(dm->device_status, NULL); - deinit_dbus(dm); + deinit_dm_dbus(dm); deinit_database(dm); diff --git a/src/device-manager.h b/src/device-manager.h index 965f485..79d103a 100644 --- a/src/device-manager.h +++ b/src/device-manager.h @@ -27,7 +27,7 @@ #include "tizen-device-def.h" #include "tizen-device.h" -typedef struct pa_device_manager pa_device_manager; +typedef struct _device_manager pa_device_manager; pa_device_manager* pa_device_manager_get(pa_core* c); pa_device_manager* pa_device_manager_ref(pa_device_manager *dm); diff --git a/src/stream-manager-dbus-priv.h b/src/stream-manager-dbus-priv.h index 28a2a3f..f0447fe 100644 --- a/src/stream-manager-dbus-priv.h +++ b/src/stream-manager-dbus-priv.h @@ -217,8 +217,8 @@ pa_dbus_interface_info stream_manager_interface_info = { #endif void send_command_signal(DBusConnection *conn, const char *name, int value); -int32_t init_dbus(pa_stream_manager *m); -void deinit_dbus(pa_stream_manager *m); +int32_t init_sm_dbus(pa_stream_manager *m); +void deinit_sm_dbus(pa_stream_manager *m); #endif diff --git a/src/stream-manager-dbus.c b/src/stream-manager-dbus.c index c989bb3..c2047eb 100644 --- a/src/stream-manager-dbus.c +++ b/src/stream-manager-dbus.c @@ -1394,7 +1394,7 @@ void send_command_signal(DBusConnection *conn, const char *name, int value) { dbus_message_unref(signal_msg); } -int32_t init_dbus(pa_stream_manager *m) { +int32_t init_sm_dbus(pa_stream_manager *m) { pa_assert(m); #ifdef USE_DBUS_PROTOCOL @@ -1425,7 +1425,7 @@ int32_t init_dbus(pa_stream_manager *m) { return 0; } -void deinit_dbus(pa_stream_manager *m) { +void deinit_sm_dbus(pa_stream_manager *m) { pa_assert(m); #ifdef USE_DBUS_PROTOCOL diff --git a/src/stream-manager.c b/src/stream-manager.c index 2cc79d1..d7a7f0f 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3069,7 +3069,7 @@ static int32_t init_ipc(pa_stream_manager *m) { pa_log_info("Initialization for IPC"); #ifdef HAVE_DBUS - if ((init_dbus(m))) + if ((init_sm_dbus(m))) return -1; #else pa_log_error("DBUS is not supported"); @@ -3082,7 +3082,7 @@ static void deinit_ipc(pa_stream_manager *m) { pa_assert(m); #ifdef HAVE_DBUS - deinit_dbus(m); + deinit_sm_dbus(m); #endif } -- 2.7.4 From 7c3c0b56e6e15cdd0a3926f060153cd1c77ab7ed Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 31 Jul 2018 10:46:33 +0900 Subject: [PATCH 03/16] device-manager-dbus: Fix to use simple array instead of struct array for out parameter [Version] 11.1.23 [Issue type] Enhancement Change-Id: I7911fdc8de2768a9b88a0acb55f11c16ad240140 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-dbus.c | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 9f7c6c3..c415c25 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.22 +Version: 11.1.23 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c index 135a110..d109fdc 100644 --- a/src/device-manager-dbus.c +++ b/src/device-manager-dbus.c @@ -986,7 +986,7 @@ static bool is_supported_sample_format(pa_sample_format_t *supported_sample_form static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_device_manager *dm; DBusMessage *reply = NULL; - DBusMessageIter msg_iter, array_iter, item_iter; + DBusMessageIter msg_iter, array_iter; dbus_int32_t device_id; pa_tz_device *device; pa_sink *sink; @@ -1023,13 +1023,11 @@ static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessag } dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(s)", &array_iter)); + pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "s", &array_iter)); for (i = 0; sink->supported_sample_formats[i] != PA_SAMPLE_MAX; i++) { format = pa_sample_format_to_string(sink->supported_sample_formats[i]); pa_log_info("%s is supported", format); - pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &item_iter)); - dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING, &format); - pa_assert_se(dbus_message_iter_close_container(&array_iter, &item_iter)); + dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &format); } pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); pa_assert_se(dbus_connection_send(conn, reply, NULL)); @@ -1160,7 +1158,7 @@ static bool is_supported_sample_rate(uint32_t *supported_sample_rates, uint32_t static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_device_manager *dm; DBusMessage *reply = NULL; - DBusMessageIter msg_iter, array_iter, item_iter; + DBusMessageIter msg_iter, array_iter; dbus_int32_t device_id; pa_tz_device *device; pa_sink *sink; @@ -1196,12 +1194,10 @@ static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage } dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(u)", &array_iter)); + pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "u", &array_iter)); for (i = 0; sink->supported_sample_rates[i]; i++) { pa_log_info("%u is supported", sink->supported_sample_rates[i]); - pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &item_iter)); - dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_UINT32, &sink->supported_sample_rates[i]); - pa_assert_se(dbus_message_iter_close_container(&array_iter, &item_iter)); + dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_UINT32, &sink->supported_sample_rates[i]); } pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter)); pa_assert_se(dbus_connection_send(conn, reply, NULL)); -- 2.7.4 From fde521ce211c2aaeb041df10e0329176a324387b Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Fri, 3 Aug 2018 10:06:43 +0900 Subject: [PATCH 04/16] device-manager-dbus: Change error type [Version] 11.1.24 [Issue type] Error value Change-Id: If037f520d67d474927d9f210dd28e350ed98ee84 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-dbus.c | 42 ++++++++++++++++----------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index c415c25..361fb39 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.23 +Version: 11.1.24 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c index d109fdc..99b7c91 100644 --- a/src/device-manager-dbus.c +++ b/src/device-manager-dbus.c @@ -1013,12 +1013,12 @@ static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessag return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } @@ -1063,18 +1063,18 @@ static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, voi return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } /* use a supported sample format selected by user */ if (!is_supported_sample_format(sink->supported_sample_formats, pa_parse_sample_format(sample_format))) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } prev_selected_sample_format = sink->selected_sample_format; @@ -1123,12 +1123,12 @@ static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, voi return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } @@ -1184,12 +1184,12 @@ static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } @@ -1233,18 +1233,18 @@ static void handle_set_sample_rate(DBusConnection *conn, DBusMessage *msg, void return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } /* use a supported sample rate selected by user */ if (!is_supported_sample_rate(sink->supported_sample_rates, sample_rate)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } prev_selected_sample_rate = sink->selected_sample_rate; @@ -1292,12 +1292,12 @@ static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } @@ -1334,11 +1334,11 @@ static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *m return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!pa_stream_manager_is_valid_stream_role(dm->core, stream_role)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } @@ -1375,7 +1375,7 @@ static void handle_get_specified_stream(DBusConnection *conn, DBusMessage *msg, return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } @@ -1415,12 +1415,12 @@ static void handle_set_avoid_resampling(DBusConnection *conn, DBusMessage *msg, return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } if (sink->avoid_resampling == avoid_resampling) { @@ -1468,12 +1468,12 @@ static void handle_get_avoid_resampling(DBusConnection *conn, DBusMessage *msg, return; } if (!is_usb_output_device(device)) { - pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) { pa_log_error("could not get sink for normal role"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); return; } -- 2.7.4 From 04e80597df8f7599fc9978d02074e5677856f859 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Wed, 29 Aug 2018 08:22:57 +0900 Subject: [PATCH 05/16] device-manager-dbus: Add new DBus method to get device state IsDeviceRunningById : arg#1 (in) int32 for device_id arg#2 (out) boolean for running state [Version] 11.1.25 [Issue type] new API Change-Id: I26c280b9cb4e5da19196af11880e38e840f8f3b8 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-dbus.c | 46 +++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 361fb39..c0eb8bd 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.24 +Version: 11.1.25 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c index 99b7c91..a878ea2 100644 --- a/src/device-manager-dbus.c +++ b/src/device-manager-dbus.c @@ -70,6 +70,10 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ @@ -191,6 +195,7 @@ do { \ /*** Defines for method handle ***/ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_device_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata); +static void handle_is_device_running_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata); static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata); @@ -215,6 +220,7 @@ static int method_call_bt_get_name(DBusConnection *conn, const char *device_path enum method_handler_index { METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST, METHOD_HANDLER_GET_DEVICE_BY_ID, + METHOD_HANDLER_IS_DEVICE_RUNNING_BY_ID, METHOD_HANDLER_IS_STREAM_ON_DEVICE, METHOD_HANDLER_GET_BT_A2DP_STATUS, METHOD_HANDLER_LOAD_SINK, @@ -243,6 +249,9 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { [METHOD_HANDLER_GET_DEVICE_BY_ID] = { .method_name = "GetDeviceById", .receive_cb = handle_get_device_by_id }, + [METHOD_HANDLER_IS_DEVICE_RUNNING_BY_ID] = { + .method_name = "IsDeviceRunningById", + .receive_cb = handle_is_device_running_by_id }, [METHOD_HANDLER_IS_STREAM_ON_DEVICE] = { .method_name = "IsStreamOnDevice", .receive_cb = handle_is_stream_on_device }, @@ -761,6 +770,43 @@ static void handle_get_device_by_id(DBusConnection *conn, DBusMessage *msg, void } } +static void handle_is_device_running_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata) +{ + pa_device_manager *manager; + DBusMessage *reply; + pa_tz_device *device; + dbus_int32_t device_id; + dbus_bool_t is_running; + + pa_assert(conn); + pa_assert(msg); + pa_assert(userdata); + + manager = (pa_device_manager *)userdata; + + pa_assert_se(dbus_message_get_args(msg, NULL, + DBUS_TYPE_INT32, &device_id, + DBUS_TYPE_INVALID)); + + pa_log_info("Is device running by id(%d)", device_id); + + if ((device = device_list_get_device_by_id(manager, device_id))) { + pa_assert_se((reply = dbus_message_new_method_return(msg))); + + is_running = pa_tz_device_is_running(device); + + pa_log_info("device(id:%d) is %s", device_id, is_running ? "Running" : "Not Running"); + + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &is_running, + DBUS_TYPE_INVALID)); + + pa_assert_se(dbus_connection_send(conn, reply, NULL)); + dbus_message_unref(reply); + } else { + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); + } +} + static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata) { pa_device_manager *manager; DBusMessage *reply; -- 2.7.4 From c209262b1567b614be29b71a6c742f8cb3673a30 Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Tue, 10 Jul 2018 11:54:24 +0900 Subject: [PATCH 06/16] device-manager: Add DEVICE_TYPE_RAOP [Version] 11.1.26 [Issue type] Feature Change-Id: I6ee61d3a0837dca6b1061153fb5c445dc0b7d3de --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 52 +++++++++++++++++++++++++++++++++ src/module-tizenaudio-policy.c | 4 +++ src/tizen-device-def.c | 8 +++++ src/tizen-device-def.h | 1 + 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index c0eb8bd..86cd8c9 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.25 +Version: 11.1.26 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 755b7ed..98abee1 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -78,6 +78,7 @@ #define DEVICE_API_BLUEZ "bluez" #define DEVICE_API_ALSA "alsa" #define DEVICE_API_NULL "null" +#define DEVICE_API_RAOP "raop" #define DEVICE_BUS_USB "usb" #define DEVICE_CLASS_SOUND "sound" #define DEVICE_CLASS_MONITOR "monitor" @@ -424,6 +425,16 @@ static bool pulse_device_is_bluez(pa_object *pdevice) { } } +static bool pulse_device_is_raop(pa_object *pdevice) { + pa_proplist *prop = pulse_device_get_proplist(pdevice); + + if (!prop) + return false; + + return pa_safe_streq(pa_proplist_gets(prop, PA_PROP_DEVICE_API), DEVICE_API_RAOP); +} + + static bool pulse_device_is_tizenaudio(pa_object *pdevice) { if (!pdevice) return false; @@ -1147,6 +1158,8 @@ static const char* pulse_device_get_system_id(pa_object *pdevice) { return pa_proplist_gets(prop, "sysfs.path"); else if (pulse_device_is_bluez(pdevice)) return pa_proplist_gets(prop, "bluez.path"); + else if (pulse_device_is_raop(pdevice)) + return pa_proplist_gets(prop, PA_PROP_DEVICE_STRING); else return NULL; } @@ -1444,6 +1457,38 @@ static void handle_bt_pulse_device(pa_object *pdevice, bool is_loaded, pa_device } } +static void handle_raop_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *dm) { + pa_tz_device *device; + const char *system_id; + + pa_assert(pdevice); + pa_assert(dm); + + pa_log_info("Handle RAOP pulse device"); + + system_id = pulse_device_get_system_id(pdevice); + + if (is_loaded) { + pa_tz_device_new_data data; + + pa_proplist *prop = pulse_device_get_proplist(pdevice); + const char *name = pa_proplist_gets(prop, PA_PROP_DEVICE_DESCRIPTION); + + pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, dm->dbus_conn); + _fill_new_data_basic(&data, DEVICE_TYPE_RAOP, DM_DEVICE_DIRECTION_OUT, false, dm); + pa_tz_device_new_data_set_name(&data, name); + pa_tz_device_new_data_set_system_id(&data, system_id); + pa_tz_device_new_data_add_sink(&data, DEVICE_ROLE_NORMAL, PA_SINK(pdevice)); + pa_tz_device_new(&data); + pa_tz_device_new_data_done(&data); + } else { + if (!(device = device_list_get_device(dm, DEVICE_TYPE_RAOP, system_id))) + pa_log_warn("Can't get RAOP device for %s", system_id); + else + pa_tz_device_free(device); + } +} + static void handle_internal_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *dm) { pa_tz_device *device; struct composite_type *ctype; @@ -1515,6 +1560,10 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, pa_dev pulse_device_set_use_internal_codec(PA_OBJECT(sink), false); handle_bt_pulse_device(PA_OBJECT(sink), true, dm); return PA_HOOK_OK; + } else if (pulse_device_is_raop(PA_OBJECT(sink))) { + pulse_device_set_use_internal_codec(PA_OBJECT(sink), false); + handle_raop_pulse_device(PA_OBJECT(sink), true, dm); + return PA_HOOK_OK; } else if (pulse_device_is_alsa(PA_OBJECT(sink)) || pulse_device_is_tizenaudio(PA_OBJECT(sink))) { pulse_device_set_use_internal_codec(PA_OBJECT(sink), true); handle_internal_pulse_device(PA_OBJECT(sink), true, dm); @@ -1542,6 +1591,9 @@ static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, pa_ } else if (pulse_device_is_bluez(PA_OBJECT(sink))) { handle_bt_pulse_device(PA_OBJECT(sink), false, dm); return PA_HOOK_OK; + } else if (pulse_device_is_raop(PA_OBJECT(sink))) { + handle_raop_pulse_device(PA_OBJECT(sink), false, dm); + return PA_HOOK_OK; } else if (pulse_device_is_alsa(PA_OBJECT(sink)) || pulse_device_is_tizenaudio(PA_OBJECT(sink))) { handle_internal_pulse_device(PA_OBJECT(sink), false, dm); return PA_HOOK_OK; diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index 3456371..ba9bb16 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -111,6 +111,7 @@ typedef enum _device_type { DEVICE_HDMI, DEVICE_FORWARDING, DEVICE_USB_AUDIO, + DEVICE_RAOP, DEVICE_UNKNOWN, DEVICE_MAX, } device_type_t; @@ -143,6 +144,9 @@ static device_type_t convert_device_type_str(const char *device) return DEVICE_FORWARDING; else if (pa_streq(device, DEVICE_TYPE_USB_AUDIO)) return DEVICE_USB_AUDIO; + else if (pa_streq(device, DEVICE_TYPE_RAOP)) + return DEVICE_RAOP; + pa_log_warn("unknown device (%s)", device); return DEVICE_UNKNOWN; diff --git a/src/tizen-device-def.c b/src/tizen-device-def.c index 37a192d..acd1fc2 100644 --- a/src/tizen-device-def.c +++ b/src/tizen-device-def.c @@ -61,6 +61,8 @@ bool device_type_is_valid(const char *device_type) { return true; else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) return true; + else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + return true; else return false; } @@ -72,6 +74,8 @@ bool device_type_is_use_external_card(const char *device_type) { return true; else if (pa_streq(device_type, DEVICE_TYPE_BT_A2DP)) return true; + else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + return true; else return false; } @@ -85,6 +89,8 @@ bool device_type_is_avail_multi_device(const char *device_type) { return true; else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) return true; + else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + return true; else return false; } @@ -151,6 +157,8 @@ bool device_type_is_valid_direction(const char *device_type, dm_device_direction return direction == DM_DEVICE_DIRECTION_BOTH; else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) return direction == DM_DEVICE_DIRECTION_BOTH || direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; + else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + return direction == DM_DEVICE_DIRECTION_OUT; else return false; } diff --git a/src/tizen-device-def.h b/src/tizen-device-def.h index 4688cec..d1bd862 100644 --- a/src/tizen-device-def.h +++ b/src/tizen-device-def.h @@ -13,6 +13,7 @@ #define DEVICE_TYPE_HDMI "hdmi" #define DEVICE_TYPE_FORWARDING "forwarding" #define DEVICE_TYPE_USB_AUDIO "usb-audio" +#define DEVICE_TYPE_RAOP "raop" #define DEVICE_TYPE_NONE "none" #define DEVICE_ROLE_NORMAL "normal" -- 2.7.4 From c0f8bb445304a585f861fe8d61eb174c0a215374 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Mon, 1 Oct 2018 16:05:42 +0900 Subject: [PATCH 07/16] device-manager-dbus: Fix bug to add condition to check 'none' for normal operation The 'none' value is to unset operation of SetSpecifcStreamOnly method. It should not be handled as an invalid value. [Version] 11.1.27 [Issue type] Bug fix Change-Id: I6daed542ec48736ed9bc00573a03a6bacf1ffc05 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-dbus.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 86cd8c9..fc46e15 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.26 +Version: 11.1.27 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c index a878ea2..5553753 100644 --- a/src/device-manager-dbus.c +++ b/src/device-manager-dbus.c @@ -1383,7 +1383,7 @@ static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *m pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } - if (!pa_stream_manager_is_valid_stream_role(dm->core, stream_role)) { + if (!pa_streq(stream_role, "none") && !pa_stream_manager_is_valid_stream_role(dm->core, stream_role)) { pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } -- 2.7.4 From e756b79bf0dea2bc7a0dd202e093f1ca558dbeef Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Mon, 1 Oct 2018 17:53:08 +0900 Subject: [PATCH 08/16] device-manager-db: Copy string value from dbus_message_get_args() [Version] 11.1.28 [Issue type] Bug fix Change-Id: Ie8c3823352a357c115a4f23f59aa88fd9a92ee8e Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-dbus.c | 3 ++- src/tizen-device.c | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index fc46e15..a78b672 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.27 +Version: 11.1.28 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c index 5553753..3587b82 100644 --- a/src/device-manager-dbus.c +++ b/src/device-manager-dbus.c @@ -1388,7 +1388,8 @@ static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *m return; } - device->specified_stream_role = stream_role; + pa_xfree(device->specified_stream_role); + device->specified_stream_role = pa_xstrdup(stream_role); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); diff --git a/src/tizen-device.c b/src/tizen-device.c index ebafc2d..56e5479 100644 --- a/src/tizen-device.c +++ b/src/tizen-device.c @@ -474,7 +474,7 @@ pa_tz_device* pa_tz_device_new(pa_tz_device_new_data *data) { device->use_internal_codec = data->use_internal_codec; device->sco_opened = false; device->is_running = false; - device->specified_stream_role = "none"; + device->specified_stream_role = pa_xstrdup("none"); if (device_type_is_use_external_card(device->type)) { if ((sink = device_get_sink(device, DEVICE_ROLE_NORMAL))) @@ -590,6 +590,7 @@ void pa_tz_device_free(pa_tz_device *device) { pa_xfree(device->type); pa_xfree(device->name); pa_xfree(device->system_id); + pa_xfree(device->specified_stream_role); pa_xfree(device); } -- 2.7.4 From bc7543428b524d85b6391d069b3414346d80a623 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Thu, 18 Oct 2018 11:49:24 +0900 Subject: [PATCH 09/16] tizenaudio-sink/source: Remove card of module argument This card argument is removed and is incorporated into the device argument. User can pass the device argument as below. e.g.) in case of card 0, device 0 device=0,0 rate=44100 device-manager is also revised to parse the device-string from device-map.json properly in case of device class is for tizen. [Version] 11.1.29 [Issue type] Bug fix Change-Id: I56d99dbc29ad7729c5842e41110f7f0c24478fee Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 51 +++--------------------------- src/module-tizenaudio-sink.c | 56 ++++++++++++++++++++++++++++----- src/module-tizenaudio-source.c | 56 ++++++++++++++++++++++++++++----- 4 files changed, 103 insertions(+), 62 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index a78b672..75a6851 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.28 +Version: 11.1.29 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 98abee1..c3a28f8 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -320,7 +320,7 @@ static dm_device_class_t device_string_get_class(const char *device_string) { } } -/* device_string looks like "alsa:0,0" +/* device_string looks like "alsa:0,0" or "tizen:0,0" * in this case name is "0,0" */ static int device_string_get_name(const char *device_string, char *name) { char *colon_p; @@ -346,42 +346,6 @@ static int device_string_get_name(const char *device_string, char *name) { return 0; } -static int device_name_get_card(const char *device_name, char *card) { - const char *name_p; - char *card_p; - - if (!strchr(device_name, ',')) { - pa_log_error("Failed to parse name : no comma"); - return -1; - } - - name_p = device_name; - card_p = card; - while (*name_p != ',') - *(card_p++) = *(name_p++); - *card_p = '\0'; - - return 0; -} - -static int device_name_get_device(const char *device_name, char *device) { - const char *comma_p; - char *device_p; - - if (!(comma_p = strchr(device_name, ','))) { - pa_log_error("Failed to parse name : no comma"); - return -1; - } - - comma_p++; - device_p = device; - while (*comma_p != '\0') - *(device_p++) = *(comma_p++); - *device_p = '\0'; - - return 0; -} - static pa_proplist* pulse_device_get_proplist(pa_object *pdevice) { if (pa_sink_isinstance(pdevice)) return PA_SINK(pdevice)->proplist; @@ -842,17 +806,10 @@ static int build_params_to_load_device(const char *device_string, const char *pa return -1; } - if (device_class == DM_DEVICE_CLASS_ALSA) { + if (device_class == DM_DEVICE_CLASS_ALSA) snprintf(target, DEVICE_PARAM_STRING_MAX, "device=hw:%s ", device_name); - } else if (device_class == DM_DEVICE_CLASS_TIZEN) { - char card[DEVICE_NAME_MAX]; - char device[DEVICE_NAME_MAX]; - - device_name_get_card(device_name, card); - device_name_get_device(device_name, device); - - snprintf(target, DEVICE_PARAM_STRING_MAX, "card=%s device=%s ", card, device); - } + else if (device_class == DM_DEVICE_CLASS_TIZEN) + snprintf(target, DEVICE_PARAM_STRING_MAX, "device=%s ", device_name); if (params) strncat(target, params, DEVICE_PARAM_STRING_MAX - strlen(target)); diff --git a/src/module-tizenaudio-sink.c b/src/module-tizenaudio-sink.c index 3d81cbb..7fe87db 100644 --- a/src/module-tizenaudio-sink.c +++ b/src/module-tizenaudio-sink.c @@ -55,8 +55,7 @@ PA_MODULE_LOAD_ONCE(false); PA_MODULE_USAGE( "sink_name= " "sink_properties= " - "card= " - "device= " + "device= " "format= " "rate= " "channels= " @@ -74,6 +73,8 @@ PA_MODULE_USAGE( /* Sink device consumes that amount of maximum buffer at every request */ #define DEFAULT_MAX_REQUEST_USEC (PA_USEC_PER_SEC * 0.032) +#define DEVICE_NAME_MAX 30 + struct userdata { pa_core *core; pa_module *module; @@ -105,7 +106,6 @@ struct userdata { static const char* const valid_modargs[] = { "sink_name", "sink_properties", - "card", "device", "format", "rate", @@ -459,6 +459,42 @@ finish: pa_log_debug("Thread shutting down"); } +static int parse_to_get_card(const char *modarg_device, char *card) { + const char *name_p; + char *card_p; + + if (!strchr(modarg_device, ',')) { + pa_log_error("Failed to parse device argument : no comma"); + return -1; + } + + name_p = modarg_device; + card_p = card; + while (*name_p != ',') + *(card_p++) = *(name_p++); + *card_p = '\0'; + + return 0; +} + +static int parse_to_get_device(const char *modarg_device, char *device) { + const char *comma_p; + char *device_p; + + if (!(comma_p = strchr(modarg_device, ','))) { + pa_log_error("Failed to parse device argument : no comma"); + return -1; + } + + comma_p++; + device_p = device; + while (*comma_p != '\0') + *(device_p++) = *(comma_p++); + *device_p = '\0'; + + return 0; +} + int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; @@ -468,7 +504,9 @@ int pa__init(pa_module*m) { uint32_t alternate_sample_rate; uint32_t block_msec; uint32_t max_request_msec; - const char *card, *device; + const char *modarg_device; + char card[DEVICE_NAME_MAX]; + char device[DEVICE_NAME_MAX]; pa_assert(m); @@ -498,9 +536,13 @@ int pa__init(pa_module*m) { u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); - if (!(card = pa_modargs_get_value(ma, "card", NULL)) || - !(device = pa_modargs_get_value(ma, "device", NULL))) { - pa_log_error("card or device are invalid"); + if (!(modarg_device = pa_modargs_get_value(ma, "device", NULL))) { + pa_log_error("device is invalid"); + goto fail; + } + + if (parse_to_get_card(modarg_device, card) || parse_to_get_device(modarg_device, device)) { + pa_log_error("failed to parse device module argument, %s", modarg_device); goto fail; } diff --git a/src/module-tizenaudio-source.c b/src/module-tizenaudio-source.c index f4c12ab..613025a 100644 --- a/src/module-tizenaudio-source.c +++ b/src/module-tizenaudio-source.c @@ -55,8 +55,7 @@ PA_MODULE_LOAD_ONCE(false); PA_MODULE_USAGE( "source_name= " "source_properties= " - "card= " - "device= " + "device= " "format= " "rate= " "channels= " @@ -70,6 +69,8 @@ PA_MODULE_USAGE( /* BLOCK_USEC should be less than amount of fragment_size * fragments */ #define BLOCK_USEC (PA_USEC_PER_SEC * 0.032) +#define DEVICE_NAME_MAX 30 + struct userdata { pa_core *core; pa_module *module; @@ -100,7 +101,6 @@ struct userdata { static const char* const valid_modargs[] = { "source_name", "source_properties", - "card", "device", "format", "rate", @@ -405,6 +405,42 @@ finish: pa_log_debug("Thread shutting down"); } +static int parse_to_get_card(const char *modarg_device, char *card) { + const char *name_p; + char *card_p; + + if (!strchr(modarg_device, ',')) { + pa_log_error("Failed to parse device argument : no comma"); + return -1; + } + + name_p = modarg_device; + card_p = card; + while (*name_p != ',') + *(card_p++) = *(name_p++); + *card_p = '\0'; + + return 0; +} + +static int parse_to_get_device(const char *modarg_device, char *device) { + const char *comma_p; + char *device_p; + + if (!(comma_p = strchr(modarg_device, ','))) { + pa_log_error("Failed to parse device argument : no comma"); + return -1; + } + + comma_p++; + device_p = device; + while (*comma_p != '\0') + *(device_p++) = *(comma_p++); + *device_p = '\0'; + + return 0; +} + int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; @@ -412,7 +448,9 @@ int pa__init(pa_module*m) { pa_modargs *ma = NULL; pa_source_new_data data; uint32_t alternate_sample_rate; - const char *card, *device; + const char *modarg_device; + char card[DEVICE_NAME_MAX]; + char device[DEVICE_NAME_MAX]; pa_assert(m); @@ -442,9 +480,13 @@ int pa__init(pa_module*m) { u->rtpoll = pa_rtpoll_new(); pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll); - if (!(card = pa_modargs_get_value(ma, "card", NULL)) || - !(device = pa_modargs_get_value(ma, "device", NULL))) { - pa_log_error("card or device are invalid"); + if (!(modarg_device = pa_modargs_get_value(ma, "device", NULL))) { + pa_log_error("device is invalid"); + goto fail; + } + + if (parse_to_get_card(modarg_device, card) || parse_to_get_device(modarg_device, device)) { + pa_log_error("failed to parse device module argument, %s", modarg_device); goto fail; } -- 2.7.4 From 20e292707eb4fda31445f0cede41bc58b8147271 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Wed, 28 Nov 2018 16:43:32 +0900 Subject: [PATCH 10/16] device-manager-dbus: Fix build break It is revised according to the pulseaudio patch. : 'Sync with upstream code' (78c3d68d7183f0daa9e0570de24f0be92bac3659) [Version] 11.1.30 [Issue type] Build break Change-Id: Ic1cf6e95b676d1fecd777d5266d9d1d4998084cb Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-dbus.c | 36 ++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 75a6851..6414212 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.29 +Version: 11.1.30 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c index 3587b82..2ad1377 100644 --- a/src/device-manager-dbus.c +++ b/src/device-manager-dbus.c @@ -1126,16 +1126,18 @@ static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, voi prev_selected_sample_format = sink->selected_sample_format; sink->selected_sample_format = pa_parse_sample_format(sample_format); - FILL_SAMPLE_SPEC_WITH_SELECTED(spec, sink); - if (pa_sink_reconfigure(sink, &spec, false) == -1) { - pa_log_error("failed to reconfigure"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); - sink->selected_sample_format = prev_selected_sample_format; - return; + if (prev_selected_sample_format != sink->selected_sample_format) { + FILL_SAMPLE_SPEC_WITH_SELECTED(spec, sink); + pa_sink_reconfigure(sink, &spec, false); + if (sink->selected_sample_format != sink->sample_spec.format) { + pa_log_error("failed to reconfigure"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); + sink->selected_sample_format = prev_selected_sample_format; + return; + } + save_preference(dm, sink); } - save_preference(dm, sink); - pa_log_info("Set sample format(%s) of the device(id:%d) successfully", sample_format, device_id); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); @@ -1296,16 +1298,18 @@ static void handle_set_sample_rate(DBusConnection *conn, DBusMessage *msg, void prev_selected_sample_rate = sink->selected_sample_rate; sink->selected_sample_rate = sample_rate; - FILL_SAMPLE_SPEC_WITH_SELECTED(spec, sink); - if (pa_sink_reconfigure(sink, &spec, false) == -1) { - pa_log_error("failed to reconfigure"); - pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); - sink->selected_sample_rate = prev_selected_sample_rate; - return; + if (prev_selected_sample_rate != sink->selected_sample_rate) { + FILL_SAMPLE_SPEC_WITH_SELECTED(spec, sink); + pa_sink_reconfigure(sink, &spec, false); + if (sink->selected_sample_rate != sink->sample_spec.rate) { + pa_log_error("failed to reconfigure"); + pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal"); + sink->selected_sample_rate = prev_selected_sample_rate; + return; + } + save_preference(dm, sink); } - save_preference(dm, sink); - pa_log_info("Set sample rate(%u) of the device(id:%d) successfully", sample_rate, device_id); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); -- 2.7.4 From 9f1bc5fd3c574249ebf312ec5a8cc7dd07dd3590 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Fri, 11 Jan 2019 14:38:21 +0900 Subject: [PATCH 11/16] tizenaudio-policy: Apply volume type to output stream of module-loopback Output stream of module-loopback has not been applied volume type. It is fixed and now it is possible to control the volume of the output stream in case of loopback feature if a volume type is defined to the loopback role in stream-map.json. Here's an example to use media volume type.(in stream-map.json) { "role":"loopback", "priority" : 2, "route-type" : "manual", "volume-types":{"in":"none","out":"media"}, "avail-in-devices":["builtin-mic","usb-audio"], "avail-out-devices":["builtin-speaker","usb-audio","bt-a2dp"], "avail-frameworks":["sound-manager"] }, Change-Id: I8335f84817ff6a3d7282c283c150c96baccf6f99 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-policy.c | 7 +++++-- src/stream-manager.c | 14 ++++++++++++++ src/stream-manager.h | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 6414212..89e2287 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.30 +Version: 11.1.31 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index ba9bb16..3f938cf 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -463,6 +463,7 @@ static void update_bt_sco_option(struct userdata *u, const char* role) { /* Load/Unload module-loopback */ static void update_loopback_module(struct userdata *u, bool load) { char *args = NULL; + const char *volume_type; pa_assert(u); @@ -472,9 +473,11 @@ static void update_loopback_module(struct userdata *u, bool load) { if (!u->loopback_args.adjust_sec) u->loopback_args.adjust_sec = LOOPBACK_DEFAULT_ADJUST_SEC; - args = pa_sprintf_malloc("sink=%s source=%s latency_msec=%d adjust_time=%d", + volume_type = pa_stream_manager_get_volume_type(u->stream_manager, STREAM_SINK_INPUT, STREAM_ROLE_LOOPBACK); + args = pa_sprintf_malloc("sink=%s source=%s latency_msec=%d adjust_time=%d sink_input_properties=%s=%s", u->loopback_args.sink->name, u->loopback_args.source->name, - u->loopback_args.latency_msec, u->loopback_args.adjust_sec); + u->loopback_args.latency_msec, u->loopback_args.adjust_sec, + PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, volume_type); if (u->module_loopback) pa_module_unload(u->module_loopback, true); diff --git a/src/stream-manager.c b/src/stream-manager.c index d7a7f0f..33ca9b3 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3116,6 +3116,20 @@ bool pa_stream_manager_is_valid_stream_role(pa_core *c, const char *role) { return true; } +const char* pa_stream_manager_get_volume_type(pa_stream_manager *m, stream_type_t stream_type, const char *role) { + stream_info *s = NULL; + + pa_assert(m); + pa_assert(role); + + if (!(s = pa_hashmap_get(m->stream_infos, role))) { + pa_log_warn("%s is not valid role, return NULL", role); + return NULL; + } + + return s->volume_types[stream_type == STREAM_SINK_INPUT ? STREAM_DIRECTION_OUT : STREAM_DIRECTION_IN]; +} + pa_stream_manager* pa_stream_manager_get(pa_core *c) { pa_stream_manager *m; diff --git a/src/stream-manager.h b/src/stream-manager.h index 85385ff..98c0804 100644 --- a/src/stream-manager.h +++ b/src/stream-manager.h @@ -147,6 +147,7 @@ int32_t pa_stream_manager_get_route_type(void *stream, stream_type_t stream_type bool pa_stream_manager_check_name_is_vstream(void *stream, stream_type_t type, bool is_new_data); bool pa_stream_manager_check_filter_apply_stream(void *stream, stream_type_t stream_type); bool pa_stream_manager_is_valid_stream_role(pa_core *c, const char *role); +const char* pa_stream_manager_get_volume_type(pa_stream_manager *m, stream_type_t stream_type, const char *role); pa_stream_manager* pa_stream_manager_get(pa_core *c); pa_stream_manager* pa_stream_manager_ref(pa_stream_manager *m); -- 2.7.4 From 65889b1aba3ec8878b036aa840f9fcb31b010ebb Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 29 Jan 2019 15:03:19 +0900 Subject: [PATCH 12/16] stream-manager: Save mute state to vconf [Version] 11.1.32 [Issue type] Enhancement Change-Id: If866ff2fe8489de4bfd28a4ceb9ccf1df27f7542 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager-dbus.c | 7 +++++++ src/stream-manager-volume-priv.h | 2 ++ src/stream-manager-volume.c | 30 +++++++++++++++++++++++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 89e2287..96a9a01 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.31 +Version: 11.1.32 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager-dbus.c b/src/stream-manager-dbus.c index c2047eb..e193bc1 100644 --- a/src/stream-manager-dbus.c +++ b/src/stream-manager-dbus.c @@ -689,6 +689,7 @@ static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void stream_type_t stream_type = STREAM_SINK_INPUT; DBusMessage *reply = NULL; pa_stream_manager *m = (pa_stream_manager*)userdata; + int ret = 0; pa_assert(conn); pa_assert(msg); @@ -712,6 +713,12 @@ static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void goto finish; } + /* check vconf update here, mute will not be set if update fails */ + if ((ret = update_mute_vconf(type, do_mute))) { + pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INTERNAL], DBUS_TYPE_INVALID)); + goto finish; + } + if (set_volume_mute_by_type(m, stream_type, type, (bool)do_mute)) pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INTERNAL], DBUS_TYPE_INVALID)); else diff --git a/src/stream-manager-volume-priv.h b/src/stream-manager-volume-priv.h index 8d9dc79..097d5e5 100644 --- a/src/stream-manager-volume-priv.h +++ b/src/stream-manager-volume-priv.h @@ -28,6 +28,7 @@ #include #define VCONFKEY_OUT_VOLUME_PREFIX "file/private/sound/volume/" +#define VCONFKEY_OUT_MUTE_PREFIX "file/private/sound/mute/" #define MASTER_VOLUME_TYPE "master" #define MASTER_VOLUME_LEVEL_MAX 100 @@ -48,5 +49,6 @@ int32_t set_volume_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, int32_t set_volume_mute_with_new_data(pa_stream_manager *m, void *stream, stream_type_t stream_type, bool volume_mute); int32_t get_volume_mute_by_idx(pa_stream_manager *m, stream_type_t stream_type, uint32_t stream_idx, bool *volume_mute); int32_t update_volume_vconf(const char *type, unsigned int value); +int32_t update_mute_vconf(const char *type, unsigned int mute); #endif diff --git a/src/stream-manager-volume.c b/src/stream-manager-volume.c index 4804264..79f3a6c 100644 --- a/src/stream-manager-volume.c +++ b/src/stream-manager-volume.c @@ -32,6 +32,7 @@ #define VOLUME_INI_DEFAULT_PATH SYSCONFDIR"/multimedia/mmfw_audio_volume.ini" /* SYSCONFDIR is defined at .spec */ #define VOLUME_INI_TUNED_PATH "/opt/system/mmfw_audio_volume.ini" #define DEFAULT_TABLE "volumes" +#define VCONF_PATH_MAX 128 #define CONVERT_TO_HAL_DIRECTION(stream_type)\ ((stream_type == STREAM_SINK_INPUT) ? DIRECTION_OUT : DIRECTION_IN) @@ -229,7 +230,7 @@ static int get_volume_value(pa_stream_manager *m, stream_type_t stream_type, boo int32_t update_volume_vconf(const char *type, unsigned int value) { - char str[128]; + char str[VCONF_PATH_MAX]; pa_snprintf(str, sizeof(str), "%s%s", VCONFKEY_OUT_VOLUME_PREFIX, type); @@ -245,6 +246,24 @@ int32_t update_volume_vconf(const char *type, unsigned int value) return 0; } +int32_t update_mute_vconf(const char *type, unsigned int mute) +{ + char str[VCONF_PATH_MAX]; + + pa_snprintf(str, sizeof(str), "%s%s", VCONFKEY_OUT_MUTE_PREFIX, type); + + /* Set mute value to VCONF */ + if ((vconf_set_bool(str, mute)) != 0) { + pa_log_error("vconf_set_bool(%s) failed...errno(%d)", + str, vconf_get_ext_errno()); + return -1; + } + + pa_log_info("mute set type(%s) value(%d)", str, mute); + + return 0; +} + int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t volume_level) { bool is_hal_volume = false; volume_info *v = NULL; @@ -738,6 +757,7 @@ int32_t init_volumes(pa_stream_manager *m) { char vconf_vol_type_addr[VCONF_ADDR_LEN] = {0,}; const char *volume_type = NULL; int level = 10; + int muted = 0; state = NULL; while ((v = pa_hashmap_iterate(m->volume_infos, &state, (const void**)&volume_type))) { memset(vconf_vol_type_addr, 0, VCONF_ADDR_LEN); @@ -748,6 +768,14 @@ int32_t init_volumes(pa_stream_manager *m) { set_volume_level_by_type(m, STREAM_SINK_INPUT, volume_type, (uint32_t)level); pa_log_debug("type[%s], current level[%u]", volume_type, v->values[STREAM_DIRECTION_OUT].current_level); } + memset(vconf_vol_type_addr, 0, VCONF_ADDR_LEN); + pa_snprintf(vconf_vol_type_addr, VCONF_ADDR_LEN, "%s%s", VCONFKEY_OUT_MUTE_PREFIX, volume_type); + if (vconf_get_bool(vconf_vol_type_addr, &muted)) + pa_log_error("failed to get mute state of the vconf[%s]", vconf_vol_type_addr); + else { + set_volume_mute_by_type(m, STREAM_SINK_INPUT, volume_type, (bool)muted); + pa_log_debug("type[%s], is_muted[%d]", volume_type, v->values[STREAM_DIRECTION_OUT].is_muted); + } } } #if 0 -- 2.7.4 From feb69e75487c19b839b25e49a050e178503f2132 Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Mon, 11 Mar 2019 11:28:29 +0900 Subject: [PATCH 13/16] device-manager-dbus: Fix SVACE defect (DEREF_OF_NULL.RET.STAT) in addition, all other usages for pa_streq is also replaced by pa_safe_streq [Version] 11.1.33 [Issue type] SVACE Change-Id: I0b959cc6687a04d0e96c603f22287c944ab9df88 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager-dbus.c | 12 +-- src/device-manager.c | 42 +++++------ src/module-sound-player.c | 4 +- src/module-tizenaudio-policy.c | 78 ++++++++++---------- src/stream-manager-dbus.c | 38 +++++----- src/stream-manager-filter.c | 8 +- src/stream-manager-restriction.c | 2 +- src/stream-manager-volume.c | 12 +-- src/stream-manager.c | 43 ++++++----- src/stream-manager.h | 23 ++++-- src/tizen-device-def.c | 126 ++++++++++++++------------------ src/tizen-device.c | 41 ++++++----- 13 files changed, 209 insertions(+), 222 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 96a9a01..579184a 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.32 +Version: 11.1.33 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager-dbus.c b/src/device-manager-dbus.c index 2ad1377..08cb2e8 100644 --- a/src/device-manager-dbus.c +++ b/src/device-manager-dbus.c @@ -498,7 +498,7 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB dbus_bool_t value; char *name = NULL; dbus_message_iter_get_basic(&variant_iter, &value); - if (pa_streq(property_name, "Connected")) { + if (pa_safe_streq(property_name, "Connected")) { pa_log_info("HFP Connection : %d", value); if (value) { method_call_bt_get_name(c, dbus_message_get_path(s), &name); @@ -512,7 +512,7 @@ static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DB } handle_device_status_changed(dm, DEVICE_TYPE_BT_SCO, name, dbus_message_get_path(s), detected); - } else if (pa_streq(property_name, "Playing")) { + } else if (pa_safe_streq(property_name, "Playing")) { pa_tz_device *device; pa_log_info("SCO Playing : %d", value); if ((device = device_list_get_device(dm, DEVICE_TYPE_BT_SCO, NULL)) != NULL) { @@ -994,7 +994,7 @@ static bool is_usb_output_device(pa_tz_device *device) { pa_assert(device); type = pa_tz_device_get_type(device); - if (!pa_streq(type, DEVICE_TYPE_USB_AUDIO)) { + if (!pa_safe_streq(type, DEVICE_TYPE_USB_AUDIO)) { pa_log_error("device(id:%d, %s) is not USB AUDIO type", pa_tz_device_get_id(device), type); return false; } @@ -1387,7 +1387,7 @@ static void handle_set_specific_stream_only(DBusConnection *conn, DBusMessage *m pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } - if (!pa_streq(stream_role, "none") && !pa_stream_manager_is_valid_stream_role(dm->core, stream_role)) { + if (!pa_safe_streq(stream_role, "none") && !pa_stream_manager_is_valid_stream_role(dm->core, stream_role)) { pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.InvalidOperation"); return; } @@ -1613,7 +1613,7 @@ static DBusHandlerResult method_call_handler(DBusConnection *c, DBusMessage *m, pa_log_info("DeviceManager Method Call Handler : path=%s, interface=%s, member=%s", path, interface, member); - if (!pa_streq(path, DBUS_OBJECT_DEVICE_MANAGER)) + if (!pa_safe_streq(path, DBUS_OBJECT_DEVICE_MANAGER)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { @@ -1867,4 +1867,4 @@ void deinit_dm_dbus(pa_device_manager *dm) { dm->dbus_conn = NULL; } } -#endif \ No newline at end of file +#endif diff --git a/src/device-manager.c b/src/device-manager.c index c3a28f8..842eb9c 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -361,7 +361,7 @@ static bool pulse_device_is_alsa(pa_object *pdevice) { return false; if ((api_name = pa_proplist_gets(prop, PA_PROP_DEVICE_API))) { - if (pa_streq(api_name, DEVICE_API_ALSA)) { + if (pa_safe_streq(api_name, DEVICE_API_ALSA)) { return true; } else { return false; @@ -379,7 +379,7 @@ static bool pulse_device_is_bluez(pa_object *pdevice) { return false; if ((api_name = pa_proplist_gets(prop, PA_PROP_DEVICE_API))) { - if (pa_streq(api_name, DEVICE_API_BLUEZ)) { + if (pa_safe_streq(api_name, DEVICE_API_BLUEZ)) { return true; } else { return false; @@ -405,10 +405,10 @@ static bool pulse_device_is_tizenaudio(pa_object *pdevice) { if (pa_sink_isinstance(pdevice)) { pa_sink *sink = PA_SINK(pdevice); - return pa_streq(sink->module->name, "module-tizenaudio-sink"); + return pa_safe_streq(sink->module->name, "module-tizenaudio-sink"); } else { pa_source *source = PA_SOURCE(pdevice); - return pa_streq(source->module->name, "module-tizenaudio-source"); + return pa_safe_streq(source->module->name, "module-tizenaudio-source"); } } @@ -420,7 +420,7 @@ static bool pulse_device_is_usb(pa_object *pdevice) { return false; if ((bus_name = pa_proplist_gets(prop, PA_PROP_DEVICE_BUS))) { - if (pa_streq(bus_name, DEVICE_BUS_USB)) { + if (pa_safe_streq(bus_name, DEVICE_BUS_USB)) { return true; } else { return false; @@ -440,10 +440,10 @@ static bool pulse_device_is_null(pa_object *pdevice) { if (pa_sink_isinstance(pdevice)) { sink = PA_SINK(pdevice); - return pa_streq(sink->module->name, "module-null-sink"); + return pa_safe_streq(sink->module->name, "module-null-sink"); } else { source = PA_SOURCE(pdevice); - return pa_streq(source->module->name, "module-null-source"); + return pa_safe_streq(source->module->name, "module-null-source"); } } @@ -530,7 +530,7 @@ static bool pulse_device_is_monitor(pa_object *pdevice) { prop = pulse_device_get_proplist(pdevice); if ((device_class = pa_proplist_gets(prop, PA_PROP_DEVICE_CLASS))) { - if (device_class && pa_streq(device_class, DEVICE_CLASS_MONITOR)) { + if (pa_safe_streq(device_class, DEVICE_CLASS_MONITOR)) { return true; } else { return false; @@ -613,10 +613,8 @@ static struct device_file_info* _device_manager_get_file_info(pa_idxset *file_in pa_assert(file_infos); PA_IDXSET_FOREACH(file_info, file_infos, file_idx) { - if (file_info->device_string) { - if (pa_streq(file_info->device_string, device_string)) { - return file_info; - } + if (pa_safe_streq(file_info->device_string, device_string)) { + return file_info; } } @@ -662,7 +660,7 @@ static struct device_status_info* _get_device_status(pa_device_manager *manager, return status_info; else if (status_info->system_id == NULL) continue; - else if (pa_streq(status_info->system_id, system_id)) + else if (pa_safe_streq(status_info->system_id, system_id)) return status_info; else continue; @@ -758,13 +756,13 @@ pa_tz_device* device_list_get_device(pa_device_manager *manager, const char *typ PA_IDXSET_FOREACH(device, manager->device_list, idx) { _type = pa_tz_device_get_type(device); _system_id = pa_tz_device_get_system_id(device); - if (pa_streq(_type, type)) { + if (pa_safe_streq(_type, type)) { if (device_type_is_avail_multi_device(type)) { if (system_id == NULL) return device; else if (_system_id == NULL) continue; - else if (pa_streq(_system_id, system_id)) + else if (pa_safe_streq(_system_id, system_id)) return device; else continue; @@ -840,7 +838,7 @@ static bool device_params_is_equal(const char *params1, const char *params2) { for (state = NULL, key = pa_modargs_iterate(modargs1, &state); key; key = pa_modargs_iterate(modargs1, &state)) { value1 = pa_modargs_get_value(modargs1, key, NULL); value2 = pa_modargs_get_value(modargs2, key, NULL); - if (!value1 || !value2 || !pa_streq(value1, value2)) { + if (!value1 || !value2 || !pa_safe_streq(value1, value2)) { equal = false; goto finish; } @@ -849,7 +847,7 @@ static bool device_params_is_equal(const char *params1, const char *params2) { for (state = NULL, key = pa_modargs_iterate(modargs2, &state); key; key = pa_modargs_iterate(modargs2, &state)) { value1 = pa_modargs_get_value(modargs1, key, NULL); value2 = pa_modargs_get_value(modargs2, key, NULL); - if (!value1 || !value2 || !pa_streq(value1, value2)) { + if (!value1 || !value2 || !pa_safe_streq(value1, value2)) { equal = false; goto finish; } @@ -931,7 +929,7 @@ static bool pulse_device_same_device_string(pa_object *pdevice, const char *devi if (pulse_device_get_device_string(pdevice, _device_string) < 0) return false; - return pa_streq(_device_string, device_string); + return pa_safe_streq(_device_string, device_string); } static const char* device_type_info_get_device_string(struct device_type_info *type_info, bool is_playback, const char *role) { @@ -1629,14 +1627,14 @@ static pa_hook_result_t sink_source_state_changed_hook_cb(pa_core *c, pa_object pa_sink *s = PA_SINK(pdevice); pa_sink_state_t state = pa_sink_get_state(s); pa_log_debug("=========== Sink(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state); - if (!s->use_internal_codec && !pa_streq(s->name, SINK_NAME_NULL)) + if (!s->use_internal_codec && !pa_safe_streq(s->name, SINK_NAME_NULL)) if ((device = pa_device_manager_get_device_with_sink(s))) pa_tz_device_set_running_and_notify(device, (state == PA_SINK_RUNNING)); } else if (pa_source_isinstance(pdevice)) { pa_source *s = PA_SOURCE(pdevice); pa_source_state_t state = pa_source_get_state(s); pa_log_debug("=========== Source(%p,%s) state has been changed to [%d](0:RUNNING, 1:IDLE, 2:SUSPEND) ==========", s, s->name, state); - if (!s->use_internal_codec && !pa_streq(s->name, SOURCE_NAME_NULL)) + if (!s->use_internal_codec && !pa_safe_streq(s->name, SOURCE_NAME_NULL)) if ((device = pa_device_manager_get_device_with_source(s))) pa_tz_device_set_running_and_notify(device, (state == PA_SOURCE_RUNNING)); } @@ -2340,7 +2338,7 @@ pa_sink* pa_device_manager_load_sink(pa_device_manager *dm, const char *type, co pa_log_info("Load Sink for '%s.%s'", type, role); PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { - if (pa_streq(type, pa_tz_device_get_type(device))) { + if (pa_safe_streq(type, pa_tz_device_get_type(device))) { if (pa_tz_device_get_sink(device, role)) { pa_log_warn("Proper sink for '%s.%s' already loaded", type, role); return NULL; @@ -2438,7 +2436,7 @@ pa_source* pa_device_manager_load_source(pa_device_manager *dm, const char *type pa_log_info("Load Source for '%s.%s'", type, role); PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { - if (pa_streq(type, pa_tz_device_get_type(device))) { + if (pa_safe_streq(type, pa_tz_device_get_type(device))) { if (pa_tz_device_get_source(device, role)) { pa_log_warn("Proper source for '%s.%s' already loaded", type, role); return NULL; diff --git a/src/module-sound-player.c b/src/module-sound-player.c index 7ef1a7e..310b631 100644 --- a/src/module-sound-player.c +++ b/src/module-sound-player.c @@ -358,7 +358,7 @@ static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, for (idx = 0; idx < METHOD_HANDLER_MAX; idx++) { if (dbus_message_is_method_call(msg, SOUND_PLAYER_INTERFACE, method_handlers[idx].method_name)) { - if (pa_streq(dbus_message_get_signature(msg), signature_args_for_in[idx])) { + if (pa_safe_streq(dbus_message_get_signature(msg), signature_args_for_in[idx])) { method_handlers[idx].receive_cb(conn, msg, userdata); return DBUS_HANDLER_RESULT_HANDLED; } else { @@ -386,7 +386,7 @@ static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member); - if (!pa_streq(path, SOUND_PLAYER_OBJECT_PATH)) + if (!pa_safe_streq(path, SOUND_PLAYER_OBJECT_PATH)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index 3f938cf..a60be73 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -126,25 +126,25 @@ int cached_connected_devices[DEVICE_MAX][CACHED_DEVICE_DIRECTION_MAX]; static device_type_t convert_device_type_str(const char *device) { - if (pa_streq(device, DEVICE_TYPE_SPEAKER)) + if (pa_safe_streq(device, DEVICE_TYPE_SPEAKER)) return DEVICE_BUILTIN_SPEAKER; - else if (pa_streq(device, DEVICE_TYPE_RECEIVER)) + else if (pa_safe_streq(device, DEVICE_TYPE_RECEIVER)) return DEVICE_BUILTIN_RECEIVER; - else if (pa_streq(device, DEVICE_TYPE_MIC)) + else if (pa_safe_streq(device, DEVICE_TYPE_MIC)) return DEVICE_BUILTIN_MIC; - else if (pa_streq(device, DEVICE_TYPE_AUDIO_JACK)) + else if (pa_safe_streq(device, DEVICE_TYPE_AUDIO_JACK)) return DEVICE_AUDIO_JACK; - else if (pa_streq(device, DEVICE_TYPE_BT_A2DP)) + else if (pa_safe_streq(device, DEVICE_TYPE_BT_A2DP)) return DEVICE_BT_A2DP; - else if (pa_streq(device, DEVICE_TYPE_BT_SCO)) + else if (pa_safe_streq(device, DEVICE_TYPE_BT_SCO)) return DEVICE_BT_SCO; - else if (pa_streq(device, DEVICE_TYPE_HDMI)) + else if (pa_safe_streq(device, DEVICE_TYPE_HDMI)) return DEVICE_HDMI; - else if (pa_streq(device, DEVICE_TYPE_FORWARDING)) + else if (pa_safe_streq(device, DEVICE_TYPE_FORWARDING)) return DEVICE_FORWARDING; - else if (pa_streq(device, DEVICE_TYPE_USB_AUDIO)) + else if (pa_safe_streq(device, DEVICE_TYPE_USB_AUDIO)) return DEVICE_USB_AUDIO; - else if (pa_streq(device, DEVICE_TYPE_RAOP)) + else if (pa_safe_streq(device, DEVICE_TYPE_RAOP)) return DEVICE_RAOP; @@ -228,7 +228,7 @@ static pa_tz_device* _get_sco_connected_device(pa_device_manager *dm) { device_list = pa_device_manager_get_device_list(dm); PA_IDXSET_FOREACH(device, device_list, device_idx) { - if (pa_streq(device->type, DEVICE_TYPE_BT_SCO)) { + if (pa_safe_streq(device->type, DEVICE_TYPE_BT_SCO)) { return device; } } @@ -256,7 +256,7 @@ static bool is_bt_a2dp_connected(pa_device_manager *dm) { device_list = pa_device_manager_get_device_list(dm); PA_IDXSET_FOREACH(device, device_list, device_idx) { - if (pa_streq(device->type, DEVICE_TYPE_BT_A2DP)) { + if (pa_safe_streq(device->type, DEVICE_TYPE_BT_A2DP)) { return true; } } @@ -346,8 +346,8 @@ static int bt_sco_open(struct userdata *u, const char *role) { return 0; } - if (pa_streq(role, STREAM_ROLE_VOICE_RECOGNITION) || - pa_streq(role, STREAM_ROLE_VOICE_RECOGNITION_SERVICE)) + if (pa_safe_streq(role, STREAM_ROLE_VOICE_RECOGNITION) || + pa_safe_streq(role, STREAM_ROLE_VOICE_RECOGNITION_SERVICE)) pa_tz_device_sco_enable_pcm(bt_device, true); if (pa_tz_device_sco_open(bt_device) < 0) { @@ -510,9 +510,9 @@ static void unload_combine_sink_module(struct userdata *u, const char *combine_s pa_assert(combine_sink_name); pa_assert(dst_sink); - if (pa_streq(combine_sink_name, SINK_NAME_COMBINED)) { + if (pa_safe_streq(combine_sink_name, SINK_NAME_COMBINED)) { combine_sink_module = &u->module_combine_sink; - } else if (pa_streq(combine_sink_name, SINK_NAME_COMBINED_EX)) { + } else if (pa_safe_streq(combine_sink_name, SINK_NAME_COMBINED_EX)) { combine_sink_module = &u->module_combine_sink_for_ex; } else { pa_log_error("unknown combine_sink_name(%s)", combine_sink_name); @@ -542,7 +542,7 @@ static bool skip_device(const char *stream_role, const char *device_type) { int sound_on = 1; - if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) + if (pa_safe_streq(device_type, DEVICE_TYPE_FORWARDING)) return true; /* get sound profile */ @@ -551,7 +551,7 @@ static bool skip_device(const char *stream_role, const char *device_type) return false; } - if (!sound_on && IS_ROLE_RINGTONE(stream_role) && pa_streq(device_type, DEVICE_TYPE_SPEAKER)) { + if (!sound_on && IS_ROLE_RINGTONE(stream_role) && pa_safe_streq(device_type, DEVICE_TYPE_SPEAKER)) { pa_log_info("sound status is 0 with ringtone-call stream, skip built-in speaker"); return true; } @@ -564,7 +564,7 @@ static bool skip_bt_sco_device(struct userdata *u, const char *stream_role, cons pa_assert(stream_role); pa_assert(device_type); - if (pa_streq(stream_role, STREAM_ROLE_VOICE_INFORMATION) && pa_streq(device_type, DEVICE_TYPE_BT_SCO)) { + if (pa_safe_streq(stream_role, STREAM_ROLE_VOICE_INFORMATION) && pa_safe_streq(device_type, DEVICE_TYPE_BT_SCO)) { if (!is_bt_sco_connected(u->device_manager)) { pa_log_warn("It is VOICE_INFORMATION, BT SCO is not connected, skip this device"); return true; @@ -592,7 +592,7 @@ static bool skip_bt_sco_device(struct userdata *u, const char *stream_role, cons static bool is_supported_stream_role_for_usb(const char *role) { pa_assert(role); - if (pa_streq(STREAM_ROLE_MEDIA, role)) + if (pa_safe_streq(STREAM_ROLE_MEDIA, role)) return true; pa_log_error("not supported role for usb(%s)", role); @@ -606,14 +606,14 @@ static bool skip_usb_device(const char *stream_role, pa_tz_device *device) { pa_assert(stream_role); pa_assert(device); - if (!pa_streq(pa_tz_device_get_type(device), DEVICE_TYPE_USB_AUDIO)) + if (!pa_safe_streq(pa_tz_device_get_type(device), DEVICE_TYPE_USB_AUDIO)) return false; if (!(specified_stream_role = pa_tz_device_get_specified_stream_role(device))) return false; if (is_supported_stream_role_for_usb(specified_stream_role) && - pa_streq(stream_role, specified_stream_role)) + pa_safe_streq(stream_role, specified_stream_role)) return false; pa_log_info("skip this usb device, stream role(%s), specified stream role(%s)", stream_role, specified_stream_role); @@ -703,7 +703,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre dm_device_id = pa_tz_device_get_id(device); pa_log_debug(" -- type[%-16s], direction[0x%x], id[%u]", dm_device_type, dm_device_direction, dm_device_id); - if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { + if (pa_safe_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { pa_log_info(" ** found a matched device: type[%-16s], direction[0x%x]", dm_device_type, dm_device_direction); if (skip_bt_sco_device(u, data->stream_role, dm_device_type)) continue; @@ -742,7 +742,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre creation_time = pa_tz_device_get_creation_time(device); pa_log_debug(" -- type[%-16s], direction[0x%x], id[%u], creation_time[%llu]", dm_device_type, dm_device_direction, dm_device_id, creation_time); - if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { + if (pa_safe_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { if (skip_bt_sco_device(u, data->stream_role, dm_device_type)) continue; if (skip_usb_device(data->stream_role, device)) @@ -779,7 +779,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre dm_device_direction = pa_tz_device_get_direction(device); pa_log_debug(" -- type[%-16s], direction[0x%x], device id[%u]", dm_device_type, dm_device_direction, *device_id); - if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { + if (pa_safe_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { pa_log_info(" ** found a matched device: type[%-16s], direction[0x%x]", device_type, dm_device_direction); if (data->stream_type == STREAM_SINK_INPUT) { if ((*(data->proper_sink)) == null_sink) @@ -808,7 +808,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre dm_device_direction = pa_tz_device_get_direction(device); pa_log_debug(" -- type[%-16s], direction[0x%x], device id[%u]", dm_device_type, dm_device_direction, *device_id); - if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { + if (pa_safe_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { pa_log_info(" ** found a matched device: type[%-16s], direction[0x%x]", device_type, dm_device_direction); /* currently, we support two sinks for combining */ if (data->stream_type == STREAM_SINK_INPUT) { @@ -819,7 +819,7 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre pa_log_warn(" -- could not get combine_sink_arg1"); } else if (!combine_sink_arg2) { sink = combine_sink_arg2 = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL); - if (sink && !pa_streq(sink->name, combine_sink_arg1->name)) { + if (sink && !pa_safe_streq(sink->name, combine_sink_arg1->name)) { uint32_t s_idx = 0; pa_log_info(" -- combine_sink_arg2[%s]", sink->name); @@ -1130,7 +1130,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ dm_device_id = pa_tz_device_get_id(device); pa_log_debug(" -- type[%-16s], direction[0x%x], id[%u]", dm_device_type, dm_device_direction, dm_device_id); - if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { + if (pa_safe_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { pa_log_debug(" ** found a matched device: type[%-16s], direction[0x%x]", dm_device_type, dm_device_direction); if (skip_usb_device(data->stream_role, device)) continue; @@ -1164,7 +1164,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_log_error("[ROUTE][AUTO] could not get sink"); } - if (pa_streq(dm_device_type, DEVICE_TYPE_BT_SCO)) { + if (pa_safe_streq(dm_device_type, DEVICE_TYPE_BT_SCO)) { if (IS_ROLE_AVAILABLE_BT_SCO_OPEN(route_info.role)) { if (update_bt_sco_state(u, true, false, route_info.role)) { pa_log_error(" ** could not open BT SCO"); @@ -1196,7 +1196,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_log_error("[ROUTE][AUTO_ALL] could not get sink from pa_device_manager_get_sink"); } else if (data->stream_type == STREAM_SINK_INPUT && !combine_sink_arg2) { sink = combine_sink_arg2 = pa_tz_device_get_sink(device, data->device_role); - if (sink && !pa_streq(sink->name, combine_sink_arg1->name)) { + if (sink && !pa_safe_streq(sink->name, combine_sink_arg1->name)) { pa_log_info("[ROUTE][AUTO_ALL] combine_sink_arg2[%s]", sink->name); /* load combine sink */ if (!u->module_combine_sink) { @@ -1261,7 +1261,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ creation_time = pa_tz_device_get_creation_time(device); pa_log_debug(" -- type[%-16s], direction[0x%x], id[%u], creation_time[%llu]", dm_device_type, dm_device_direction, dm_device_id, creation_time); - if (pa_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { + if (pa_safe_streq(device_type, dm_device_type) && IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) { if (skip_usb_device(data->stream_role, device)) continue; use_internal_codec = pa_tz_device_is_use_internal_codec(device); @@ -1303,7 +1303,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_log_error("[ROUTE][AUTO_LAST_CONN] could not get sink"); } - if (pa_streq(dm_device_type, DEVICE_TYPE_BT_SCO)) { + if (pa_safe_streq(dm_device_type, DEVICE_TYPE_BT_SCO)) { if (IS_ROLE_AVAILABLE_BT_SCO_OPEN(route_info.role)) { if (update_bt_sco_state(u, true, false, route_info.role)) { pa_log_error(" ** could not open BT SCO"); @@ -1332,13 +1332,13 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ if (!(device = pa_device_manager_get_device_by_id(u->device_manager, *device_id))) continue; dm_device_type = pa_tz_device_get_type(device); - if (!pa_streq(device_type, dm_device_type)) + if (!pa_safe_streq(device_type, dm_device_type)) continue; dm_device_direction = pa_tz_device_get_direction(device); pa_log_debug(" ** found a matched device: type[%-16s], direction[0x%x]", dm_device_type, dm_device_direction); /* Check for availability for opening Bluetooth SCO */ - if (pa_streq(dm_device_type, DEVICE_TYPE_BT_SCO) && IS_ROLE_AVAILABLE_BT_SCO_OPEN(route_info.role)) { + if (pa_safe_streq(dm_device_type, DEVICE_TYPE_BT_SCO) && IS_ROLE_AVAILABLE_BT_SCO_OPEN(route_info.role)) { /* update BT SCO: open */ if (update_bt_sco_state(u, true, false, route_info.role)) { pa_log_error(" ** could not open BT SCO"); @@ -1350,7 +1350,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ update_bt_sco_state(u, false, false, NULL); } /* Check for in/out devices in case of loopback */ - if (pa_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { + if (pa_safe_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { if ((data->stream_type == STREAM_SINK_INPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_OUT)) u->loopback_args.sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL); else if ((data->stream_type == STREAM_SOURCE_OUTPUT) && (dm_device_direction & DM_DEVICE_DIRECTION_IN)) @@ -1366,7 +1366,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ } } } - if (pa_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { + if (pa_safe_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { /* load module-loopback */ if (u->loopback_args.sink && u->loopback_args.source) update_loopback_module(u, true); @@ -1396,11 +1396,11 @@ static pa_hook_result_t update_info_hook_cb(pa_core *c, pa_stream_manager_hook_d pa_assert(data); pa_assert(u); - if (pa_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { + if (pa_safe_streq(data->stream_role, STREAM_ROLE_LOOPBACK)) { pa_log_info("[UPDATE] stream_role(%s) [name(%s)/value(%d)]", data->stream_role, data->name, data->value); - if (pa_streq(data->name, MSG_FOR_LOOPBACK_ARG_LATENCY)) + if (pa_safe_streq(data->name, MSG_FOR_LOOPBACK_ARG_LATENCY)) u->loopback_args.latency_msec = data->value; - else if (pa_streq(data->name, MSG_FOR_LOOPBACK_ARG_ADJUST_TIME)) + else if (pa_safe_streq(data->name, MSG_FOR_LOOPBACK_ARG_ADJUST_TIME)) u->loopback_args.adjust_sec = data->value; } diff --git a/src/stream-manager-dbus.c b/src/stream-manager-dbus.c index e193bc1..5c402ec 100644 --- a/src/stream-manager-dbus.c +++ b/src/stream-manager-dbus.c @@ -568,9 +568,9 @@ static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) + if (pa_safe_streq(direction, "in")) stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) + else if (pa_safe_streq(direction, "out")) stream_type = STREAM_SINK_INPUT; else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INTERNAL], DBUS_TYPE_INVALID)); @@ -617,9 +617,9 @@ static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) + if (pa_safe_streq(direction, "in")) stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) + else if (pa_safe_streq(direction, "out")) stream_type = STREAM_SINK_INPUT; else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); @@ -660,9 +660,9 @@ static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) + if (pa_safe_streq(direction, "in")) stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) + else if (pa_safe_streq(direction, "out")) stream_type = STREAM_SINK_INPUT; else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); @@ -704,9 +704,9 @@ static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) + if (pa_safe_streq(direction, "in")) stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) + else if (pa_safe_streq(direction, "out")) stream_type = STREAM_SINK_INPUT; else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INTERNAL], DBUS_TYPE_INVALID)); @@ -749,9 +749,9 @@ static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) + if (pa_safe_streq(direction, "in")) stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) + else if (pa_safe_streq(direction, "out")) stream_type = STREAM_SINK_INPUT; else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_UINT32, 0, DBUS_TYPE_INVALID)); @@ -793,10 +793,10 @@ static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *ms pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) { + if (pa_safe_streq(direction, "in")) { stream_type = STREAM_SOURCE_OUTPUT; streams = m->core->source_outputs; - } else if (pa_streq(direction, "out")) { + } else if (pa_safe_streq(direction, "out")) { stream_type = STREAM_SINK_INPUT; streams = m->core->sink_inputs; } else { @@ -864,9 +864,9 @@ static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMess pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) { + if (pa_safe_streq(direction, "in")) { dm_device_direction = DM_DEVICE_DIRECTION_IN; - } else if (pa_streq(direction, "out")) { + } else if (pa_safe_streq(direction, "out")) { dm_device_direction = DM_DEVICE_DIRECTION_OUT; } else { pa_log_error("invalid direction[%s]", direction); @@ -1121,7 +1121,7 @@ static void handle_update_call_parameters(DBusConnection *conn, DBusMessage *msg /* Currently, we only use network band */ route_option.name = "call-wideband"; - if (pa_streq(network_band, "wb")) + if (pa_safe_streq(network_band, "wb")) route_option.value = 1; else route_option.value = 0; @@ -1286,9 +1286,9 @@ static void handle_check_stream_exist_by_pid(DBusConnection *conn, DBusMessage * pa_assert_se((reply = dbus_message_new_method_return(msg))); - if (pa_streq(direction, "in")) + if (pa_safe_streq(direction, "in")) stream_type = STREAM_SOURCE_OUTPUT; - else if (pa_streq(direction, "out")) + else if (pa_safe_streq(direction, "out")) stream_type = STREAM_SINK_INPUT; else { pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_ERROR_INVALID_ARGUMENT], @@ -1320,7 +1320,7 @@ static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, for (idx = 0; idx < METHOD_HANDLER_MAX; idx++) { if (dbus_message_is_method_call(msg, STREAM_MANAGER_INTERFACE, method_handlers[idx].method_name)) { pa_log_debug("Message signature [%s] (Expected [%s])", dbus_message_get_signature(msg), signature_args_for_in[idx]); - if (pa_streq(dbus_message_get_signature(msg), signature_args_for_in[idx])) { + if (pa_safe_streq(dbus_message_get_signature(msg), signature_args_for_in[idx])) { method_handlers[idx].receive_cb(conn, msg, userdata); return DBUS_HANDLER_RESULT_HANDLED; } else { @@ -1348,7 +1348,7 @@ static DBusHandlerResult method_handler_for_vt(DBusConnection *c, DBusMessage *m pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member); - if (!pa_streq(path, STREAM_MANAGER_OBJECT_PATH)) + if (!pa_safe_streq(path, STREAM_MANAGER_OBJECT_PATH)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) { diff --git a/src/stream-manager-filter.c b/src/stream-manager-filter.c index 9aeb9cb..a0d0842 100644 --- a/src/stream-manager-filter.c +++ b/src/stream-manager-filter.c @@ -202,7 +202,7 @@ static void update_prop_filter_apply_params(pa_sink_input *si, filter_info *f, c int32_t apply_filter_to_sink_input(pa_sink_input *si, filter_info *f, bool need_to_hook) { pa_assert(si); - if (f && (!f->filter_apply || pa_streq(f->filter_apply, ""))) { + if (f && (!f->filter_apply || pa_safe_streq(f->filter_apply, ""))) { pa_log_error("Try to applying empty filter module"); return -1; } @@ -326,7 +326,7 @@ int32_t control_filter(pa_stream_manager *m, const char *filter_name, const char uint32_t s_idx = 0; pa_sink *s = NULL; - if (pa_streq(filter_name, "") || pa_streq(filter_controls, "")) { + if (pa_safe_streq(filter_name, "") || pa_safe_streq(filter_controls, "")) { pa_log_error("Empty filter name or controls"); return -1; } @@ -509,7 +509,7 @@ void init_filters(pa_stream_manager *m) { /* Load module-filter-apply */ PA_IDXSET_FOREACH(i, m->core->modules, idx) { - if (pa_streq(i->name, MODULE_FILTER_APPLY)) { + if (pa_safe_streq(i->name, MODULE_FILTER_APPLY)) { module = i; pa_log("module-filter-apply loaded already"); break; @@ -531,7 +531,7 @@ void deinit_filters(pa_stream_manager *m) { /* Unload module-filter-apply */ PA_IDXSET_FOREACH(i, m->core->modules, idx) { - if (pa_streq(i->name, MODULE_FILTER_APPLY)) { + if (pa_safe_streq(i->name, MODULE_FILTER_APPLY)) { pa_module_unload(i, true); pa_log("module-filter-apply unloaded"); break; diff --git a/src/stream-manager-restriction.c b/src/stream-manager-restriction.c index fa5ec58..818b6c5 100644 --- a/src/stream-manager-restriction.c +++ b/src/stream-manager-restriction.c @@ -33,7 +33,7 @@ int32_t handle_restrictions(pa_stream_manager *m, const char *name, uint32_t val pa_assert(m); - if (pa_streq(name, STREAM_MANAGER_METHOD_ARGS_BLOCK_RECORDING_MEDIA) ) { + if (pa_safe_streq(name, STREAM_MANAGER_METHOD_ARGS_BLOCK_RECORDING_MEDIA) ) { if (value == 1) { pa_log_info("block MEDIA recording"); m->restrictions.block_recording_media = true; diff --git a/src/stream-manager-volume.c b/src/stream-manager-volume.c index 79f3a6c..db3c4b7 100644 --- a/src/stream-manager-volume.c +++ b/src/stream-manager-volume.c @@ -297,18 +297,18 @@ int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type return -1; } - if (pa_streq(volume_type, MASTER_VOLUME_TYPE) && MASTER_VOLUME_LEVEL_MAX < volume_level) { + if (pa_safe_streq(volume_type, MASTER_VOLUME_TYPE) && MASTER_VOLUME_LEVEL_MAX < volume_level) { pa_log_error("could not set volume level of MASTER type, out of range[%u]", volume_level); return -1; } v->values[stream_type].current_level = volume_level; - if (is_hal_volume && pa_streq(volume_type, MASTER_VOLUME_TYPE)) { + if (is_hal_volume && pa_safe_streq(volume_type, MASTER_VOLUME_TYPE)) { /* no need to update the value of pulseaudio stream */ return 0; } - if (!pa_streq(volume_type, MASTER_VOLUME_TYPE)) { + if (!pa_safe_streq(volume_type, MASTER_VOLUME_TYPE)) { if (get_volume_value(m, stream_type, is_hal_volume, volume_type, volume_level, &volume_linear)) return -1; @@ -320,7 +320,7 @@ int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); /* Update volume level of stream if it has requested the volume type */ - if (pa_streq(volume_type_str, volume_type)) { + if (pa_safe_streq(volume_type_str, volume_type)) { if (modifier_gain) { if (m->volume_modifiers) { if ((modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain))) { @@ -411,7 +411,7 @@ int32_t get_volume_level_by_type(pa_stream_manager *m, pa_volume_get_command_t c } } else if (command == GET_VOLUME_MAX_LEVEL) { /* If it is the master volume type */ - if (pa_streq(volume_type, MASTER_VOLUME_TYPE)) { + if (pa_safe_streq(volume_type, MASTER_VOLUME_TYPE)) { *volume_level = MASTER_VOLUME_LEVEL_MAX; } else { /* Get max level */ @@ -574,7 +574,7 @@ int32_t set_volume_mute_by_type(pa_stream_manager *m, stream_type_t stream_type, } /* Update mute of stream if it has requested the volume type */ - if (pa_streq(volume_type_str, volume_type)) { + if (pa_safe_streq(volume_type_str, volume_type)) { if (stream_type == STREAM_SINK_INPUT) pa_sink_input_set_mute((pa_sink_input*)s, volume_mute, true); else if (stream_type == STREAM_SOURCE_OUTPUT) diff --git a/src/stream-manager.c b/src/stream-manager.c index 33ca9b3..0370154 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -146,15 +146,15 @@ static int32_t convert_route_type(const char *route_type_str, stream_route_type_ pa_assert(route_type); pa_assert(route_type_str); - if (pa_streq("auto", route_type_str)) + if (pa_safe_streq("auto", route_type_str)) *route_type = STREAM_ROUTE_TYPE_AUTO; - else if (pa_streq("auto-last-connected", route_type_str)) + else if (pa_safe_streq("auto-last-connected", route_type_str)) *route_type = STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED; - else if (pa_streq("auto-all", route_type_str)) + else if (pa_safe_streq("auto-all", route_type_str)) *route_type = STREAM_ROUTE_TYPE_AUTO_ALL; - else if (pa_streq("manual", route_type_str)) + else if (pa_safe_streq("manual", route_type_str)) *route_type = STREAM_ROUTE_TYPE_MANUAL; - else if (pa_streq("manual-ext", route_type_str)) + else if (pa_safe_streq("manual-ext", route_type_str)) *route_type = STREAM_ROUTE_TYPE_MANUAL_EXT; else { ret = -1; @@ -874,7 +874,7 @@ static bool check_name_to_skip(pa_stream_manager *m, process_command_type_t comm if (command == PROCESS_COMMAND_PREPARE && is_new_data) { if ((name = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_NAME))) { for (i = 0; i < NAME_FOR_SKIP_MAX; i++) - if (pa_streq(name, stream_manager_media_names_for_skip[i])) { + if (pa_safe_streq(name, stream_manager_media_names_for_skip[i])) { ret = true; pa_proplist_sets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE, SKIP_ROLE); break; @@ -887,7 +887,7 @@ static bool check_name_to_skip(pa_stream_manager *m, process_command_type_t comm else role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); - if (role && pa_streq(role, SKIP_ROLE)) + if (pa_safe_streq(role, SKIP_ROLE)) ret = true; } @@ -904,7 +904,7 @@ static bool check_role_to_skip(pa_stream_manager *m, process_command_type_t comm if ((s = pa_hashmap_get(m->stream_infos, role))) ret = false; - if (s && pa_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING) && + if (s && pa_safe_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING) && (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED || command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED)) ret = true; @@ -943,11 +943,10 @@ static bool check_name_is_vstream(void *stream, stream_type_t type, bool is_new_ name = pa_proplist_gets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_NAME); else name = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_NAME); - if (name) { - if (pa_streq(name, VIRTUAL_STREAM_NAME)) { - ret = true; - pa_log_info("name is [%s]", name); - } + + if (pa_safe_streq(name, VIRTUAL_STREAM_NAME)) { + ret = true; + pa_log_info("name is [%s]", name); } return ret; @@ -1005,7 +1004,7 @@ static bool update_volume_type_of_stream(pa_stream_manager *m, void *stream, str if ((s = pa_hashmap_get(m->stream_infos, role))) volume_type = s->volume_types[type]; - if (volume_type && (!pa_streq(volume_type, "none"))) { + if (volume_type && (!pa_safe_streq(volume_type, "none"))) { pa_proplist_sets(GET_STREAM_NEW_PROPLIST(stream, type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, volume_type); ret = true; } else @@ -1684,7 +1683,7 @@ static void update_mirroring_streams(pa_stream_manager *m, pa_source_output *o, pa_assert(o); if ((role = pa_proplist_gets(GET_STREAM_PROPLIST(o, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROLE)) && - pa_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) { + pa_safe_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) { if (put) pa_idxset_put(m->mirroring_streams, o, NULL); else @@ -1812,7 +1811,7 @@ process_stream_result_t process_stream(pa_stream_manager *m, void *stream, strea goto finish; } /* load forwarding device */ - if (type == STREAM_SOURCE_OUTPUT && pa_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) + if (type == STREAM_SOURCE_OUTPUT && pa_safe_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) update_forwarding_device(m, true); } /* update the priority of this stream */ @@ -1926,7 +1925,7 @@ process_stream_result_t process_stream(pa_stream_manager *m, void *stream, strea role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); if (role) { /* unload forwarding device */ - if (type == STREAM_SOURCE_OUTPUT && pa_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) + if (type == STREAM_SOURCE_OUTPUT && pa_safe_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) update_forwarding_device(m, false); /* skip roles */ @@ -2326,7 +2325,7 @@ static void find_next_device_for_auto_route(pa_stream_manager *m, stream_route_t if (route_type == STREAM_ROUTE_TYPE_AUTO) { PA_IDXSET_FOREACH(device_type, devices, idx) { - if (pa_streq(device_type, cur_device_type)) { + if (pa_safe_streq(device_type, cur_device_type)) { ret_next = true; continue; } @@ -2386,12 +2385,12 @@ static void is_available_device_for_auto_route(pa_stream_manager *m, stream_rout PA_IDXSET_FOREACH(device_type, devices, idx) { if (route_type == STREAM_ROUTE_TYPE_AUTO) { - if (pa_streq(device_type, cur_device_type)) { + if (pa_safe_streq(device_type, cur_device_type)) { pa_log_debug("cur_device[%s]'s priority is more higher than new_device[%s]", cur_device_type, new_device_type); break; } } - if (pa_streq(device_type, new_device_type)) { + if (pa_safe_streq(device_type, new_device_type)) { *available = true; break; } @@ -2700,7 +2699,7 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_ PA_IDXSET_FOREACH(s, streams, s_idx) { /* streams: core->source_outputs/core->sink_inputs */ if ((cur_device_type = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV))) { for (cnt = 0; cached_prev_dev_list[cnt].device_type; cnt++) { - if (pa_streq(cur_device_type, cached_prev_dev_list[cnt].device_type)) + if (pa_safe_streq(cur_device_type, cached_prev_dev_list[cnt].device_type)) cached_prev_dev_list[cnt].count++; } } @@ -3006,7 +3005,7 @@ static void subscribe_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t return; } name = pa_proplist_gets(client->proplist, PA_PROP_APPLICATION_NAME); - if (!name || (name && !pa_streq(name, STREAM_MANAGER_CLIENT_NAME))) { + if (!pa_safe_streq(name, STREAM_MANAGER_CLIENT_NAME)) { pa_log_warn(" - this is not a client(%s) that we should take care of, skip it", name); return; } diff --git a/src/stream-manager.h b/src/stream-manager.h index 98c0804..55f2572 100644 --- a/src/stream-manager.h +++ b/src/stream-manager.h @@ -25,7 +25,8 @@ #include #define IS_AUTO_ROUTE_TYPE_SERIES(route_type_enum) \ - ((route_type_enum == STREAM_ROUTE_TYPE_AUTO) || (route_type_enum == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) || \ + ((route_type_enum == STREAM_ROUTE_TYPE_AUTO) || \ + (route_type_enum == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED) || \ (route_type_enum == STREAM_ROUTE_TYPE_AUTO_ALL)) #define IS_MANUAL_ROUTE_TYPE_SERIES(route_type_enum) \ @@ -41,17 +42,23 @@ (route_type_str && !pa_atoi(route_type_str, (int32_t*)&route_type) && (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED)) #define IS_ROLE_COMMUNICATION(stream_role) \ - (stream_role && (pa_streq(stream_role, STREAM_ROLE_CALL_VOICE) || pa_streq(stream_role, STREAM_ROLE_CALL_VIDEO) || \ - pa_streq(stream_role, STREAM_ROLE_VOIP) || pa_streq(stream_role, STREAM_ROLE_RINGBACKTONE_CALL))) + (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE) || \ + pa_safe_streq(stream_role, STREAM_ROLE_CALL_VIDEO) || \ + pa_safe_streq(stream_role, STREAM_ROLE_VOIP) || \ + pa_safe_streq(stream_role, STREAM_ROLE_RINGBACKTONE_CALL)) #define IS_ROLE_RINGTONE(stream_role) \ - (pa_streq(stream_role, STREAM_ROLE_RINGTONE_CALL) || pa_streq(stream_role, STREAM_ROLE_RINGTONE_VOIP)) + (pa_safe_streq(stream_role, STREAM_ROLE_RINGTONE_CALL) || \ + pa_safe_streq(stream_role, STREAM_ROLE_RINGTONE_VOIP)) #define IS_ROLE_AVAILABLE_BT_SCO_OPEN(stream_role) \ - (stream_role && (pa_streq(stream_role, STREAM_ROLE_CALL_VOICE) || pa_streq(stream_role, STREAM_ROLE_CALL_VIDEO) || \ - pa_streq(stream_role, STREAM_ROLE_VOIP) || pa_streq(stream_role, STREAM_ROLE_RINGBACKTONE_CALL) || \ - pa_streq(stream_role, STREAM_ROLE_VOICE_RECOGNITION) || pa_streq(stream_role, STREAM_ROLE_VOICE_RECOGNITION_SERVICE) || \ - pa_streq(stream_role, STREAM_ROLE_VOICE_INFORMATION))) + (pa_safe_streq(stream_role, STREAM_ROLE_CALL_VOICE) || \ + pa_safe_streq(stream_role, STREAM_ROLE_CALL_VIDEO) || \ + pa_safe_streq(stream_role, STREAM_ROLE_VOIP) || \ + pa_safe_streq(stream_role, STREAM_ROLE_RINGBACKTONE_CALL) || \ + pa_safe_streq(stream_role, STREAM_ROLE_VOICE_RECOGNITION) || \ + pa_safe_streq(stream_role, STREAM_ROLE_VOICE_RECOGNITION_SERVICE) || \ + pa_safe_streq(stream_role, STREAM_ROLE_VOICE_INFORMATION)) #define CONVERT_TO_DEVICE_ROLE(x_stream_role, x_device_role) \ do { \ diff --git a/src/tizen-device-def.c b/src/tizen-device-def.c index acd1fc2..22f6612 100644 --- a/src/tizen-device-def.c +++ b/src/tizen-device-def.c @@ -14,7 +14,7 @@ static inline bool pa_safe_streq2(const char *a, const char *b) { if (a && b) - return pa_streq(a, b); + return pa_safe_streq(a, b); if (!a && !b) return true; return false; @@ -24,87 +24,77 @@ bool device_type_is_equal(const char *device_type1, const char *device_type2) { pa_assert(device_type1); pa_assert(device_type2); - return pa_streq(device_type1, device_type2); + return pa_safe_streq(device_type1, device_type2); } bool device_type_is_builtin(const char *device_type) { - if (!device_type) - return false; - else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + if (pa_safe_streq(device_type, DEVICE_TYPE_SPEAKER)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_RECEIVER)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_MIC)) return true; else return false; } bool device_type_is_valid(const char *device_type) { - if (!device_type) - return false; - else if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + if (pa_safe_streq(device_type, DEVICE_TYPE_SPEAKER)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_RECEIVER)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_MIC)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_BT_A2DP)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_BT_A2DP)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_BT_SCO)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_BT_SCO)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_HDMI)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_FORWARDING)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_USB_AUDIO)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_RAOP)) return true; else return false; } bool device_type_is_use_external_card(const char *device_type) { - if (!device_type) - return false; - else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + if (pa_safe_streq(device_type, DEVICE_TYPE_USB_AUDIO)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_BT_A2DP)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_BT_A2DP)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_RAOP)) return true; else return false; } bool device_type_is_avail_multi_device(const char *device_type) { - if (!device_type) - return false; - else if (pa_streq(device_type, DEVICE_TYPE_BT_A2DP)) + if (pa_safe_streq(device_type, DEVICE_TYPE_BT_A2DP)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_BT_SCO)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_BT_SCO)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_USB_AUDIO)) return true; - else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_RAOP)) return true; else return false; } bool device_type_is_need_detect(const char *type) { - if (!type) - return false; - else if (pa_streq(type, DEVICE_TYPE_AUDIO_JACK)) + if (pa_safe_streq(type, DEVICE_TYPE_AUDIO_JACK)) return true; - else if (pa_streq(type, DEVICE_TYPE_HDMI)) + else if (pa_safe_streq(type, DEVICE_TYPE_HDMI)) return true; - else if (pa_streq(type, DEVICE_TYPE_FORWARDING)) + else if (pa_safe_streq(type, DEVICE_TYPE_FORWARDING)) return true; - else if (pa_streq(type, DEVICE_TYPE_BT_SCO)) + else if (pa_safe_streq(type, DEVICE_TYPE_BT_SCO)) return true; else return false; @@ -117,17 +107,17 @@ bool device_type_is_need_detect(const char *type) { dm_device_direction_t device_type_get_static_direction(const char *type) { if (!type) return DM_DEVICE_DIRECTION_NONE; - else if (pa_streq(type, DEVICE_TYPE_SPEAKER)) + else if (pa_safe_streq(type, DEVICE_TYPE_SPEAKER)) return DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(type, DEVICE_TYPE_RECEIVER)) + else if (pa_safe_streq(type, DEVICE_TYPE_RECEIVER)) return DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(type, DEVICE_TYPE_MIC)) + else if (pa_safe_streq(type, DEVICE_TYPE_MIC)) return DM_DEVICE_DIRECTION_IN; else if (device_type_is_equal(type, DEVICE_TYPE_BT_SCO)) return DM_DEVICE_DIRECTION_BOTH; - else if (pa_streq(type, DEVICE_TYPE_HDMI)) + else if (pa_safe_streq(type, DEVICE_TYPE_HDMI)) return DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(type, DEVICE_TYPE_FORWARDING)) + else if (pa_safe_streq(type, DEVICE_TYPE_FORWARDING)) return DM_DEVICE_DIRECTION_BOTH; else return DM_DEVICE_DIRECTION_NONE; @@ -139,34 +129,33 @@ bool device_type_is_valid_direction(const char *device_type, dm_device_direction if (!device_type || direction == DM_DEVICE_DIRECTION_NONE) return false; - if (pa_streq(device_type, DEVICE_TYPE_SPEAKER)) + if (pa_safe_streq(device_type, DEVICE_TYPE_SPEAKER)) return direction == DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(device_type, DEVICE_TYPE_RECEIVER)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_RECEIVER)) return direction == DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(device_type, DEVICE_TYPE_MIC)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_MIC)) return direction == DM_DEVICE_DIRECTION_IN; - else if (pa_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_AUDIO_JACK)) return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_BOTH; - else if (pa_streq(device_type, DEVICE_TYPE_BT_SCO)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_BT_SCO)) return direction == DM_DEVICE_DIRECTION_BOTH; - else if (pa_streq(device_type, DEVICE_TYPE_BT_A2DP)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_BT_A2DP)) return direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; - else if (pa_streq(device_type, DEVICE_TYPE_HDMI)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_HDMI)) return direction == DM_DEVICE_DIRECTION_OUT; - else if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_FORWARDING)) return direction == DM_DEVICE_DIRECTION_BOTH; - else if (pa_streq(device_type, DEVICE_TYPE_USB_AUDIO)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_USB_AUDIO)) return direction == DM_DEVICE_DIRECTION_BOTH || direction == DM_DEVICE_DIRECTION_OUT || direction == DM_DEVICE_DIRECTION_IN; - else if (pa_streq(device_type, DEVICE_TYPE_RAOP)) + else if (pa_safe_streq(device_type, DEVICE_TYPE_RAOP)) return direction == DM_DEVICE_DIRECTION_OUT; else return false; } const char* device_direction_to_string(dm_device_direction_t direction) { - if (direction > DM_DEVICE_DIRECTION_BOTH) { + if (direction > DM_DEVICE_DIRECTION_BOTH) return NULL; - } if (direction == DM_DEVICE_DIRECTION_NONE) return DEVICE_DIRECTION_STR_NONE; @@ -181,40 +170,33 @@ const char* device_direction_to_string(dm_device_direction_t direction) { } bool device_role_is_valid(const char *device_role) { - if (!device_role) - return false; - else if (pa_streq(device_role, DEVICE_ROLE_NORMAL)) + if (pa_safe_streq(device_role, DEVICE_ROLE_NORMAL)) return true; - else if (pa_streq(device_role, DEVICE_ROLE_CALL_VOICE)) + else if (pa_safe_streq(device_role, DEVICE_ROLE_CALL_VOICE)) return true; - else if (pa_streq(device_role, DEVICE_ROLE_CALL_VIDEO)) + else if (pa_safe_streq(device_role, DEVICE_ROLE_CALL_VIDEO)) return true; - else if (pa_streq(device_role, DEVICE_ROLE_VOIP)) + else if (pa_safe_streq(device_role, DEVICE_ROLE_VOIP)) return true; - else if (pa_streq(device_role, DEVICE_ROLE_LOW_LATENCY)) + else if (pa_safe_streq(device_role, DEVICE_ROLE_LOW_LATENCY)) return true; - else if (pa_streq(device_role, DEVICE_ROLE_HIGH_LATENCY)) + else if (pa_safe_streq(device_role, DEVICE_ROLE_HIGH_LATENCY)) return true; - else if (pa_streq(device_role, DEVICE_ROLE_UHQA)) + else if (pa_safe_streq(device_role, DEVICE_ROLE_UHQA)) return true; else return false; } dm_device_direction_t device_direction_to_int(const char *device_direction) { - if (!device_direction) { - return -1; - } - - if (pa_streq(device_direction, DEVICE_DIRECTION_STR_NONE)) { + if (pa_safe_streq(device_direction, DEVICE_DIRECTION_STR_NONE)) return DM_DEVICE_DIRECTION_NONE; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_OUT)) { + else if (pa_safe_streq(device_direction, DEVICE_DIRECTION_STR_OUT)) return DM_DEVICE_DIRECTION_OUT; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_IN)) { + else if (pa_safe_streq(device_direction, DEVICE_DIRECTION_STR_IN)) return DM_DEVICE_DIRECTION_IN; - } else if (pa_streq(device_direction, DEVICE_DIRECTION_STR_BOTH)) { + else if (pa_safe_streq(device_direction, DEVICE_DIRECTION_STR_BOTH)) return DM_DEVICE_DIRECTION_BOTH; - } else { + else return -1; - } } diff --git a/src/tizen-device.c b/src/tizen-device.c index 56e5479..81f3401 100644 --- a/src/tizen-device.c +++ b/src/tizen-device.c @@ -696,7 +696,7 @@ int pa_tz_device_get_product_id(pa_tz_device *device) { char* pa_tz_device_get_specified_stream_role(pa_tz_device *device) { pa_assert(device); - if (pa_streq("none", device->specified_stream_role)) + if (pa_safe_streq("none", device->specified_stream_role)) return NULL; return device->specified_stream_role; @@ -861,33 +861,34 @@ static int method_call_bt_sco_get_property(pa_dbus_connection *conn, bool *is_wi while (dbus_message_iter_get_arg_type(&reply_iter_entry) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter dict_entry, dict_entry_val; + dbus_message_iter_recurse(&reply_iter_entry, &dict_entry); dbus_message_iter_get_basic(&dict_entry, &property); pa_log_debug("String received = %s", property); - if (property) { - if (pa_streq("codec", property) && is_wide_band) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_UINT32) - continue; - dbus_message_iter_get_basic(&dict_entry_val, &codec); - pa_log_debug("Codec = [%d]", codec); - *is_wide_band = (codec == BT_MSBC_CODEC_ID) ? true : false; - } else if (pa_streq("nrec", property) && is_nrec) { - dbus_message_iter_next(&dict_entry); - dbus_message_iter_recurse(&dict_entry, &dict_entry_val); - if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_BOOLEAN) - continue; - dbus_message_iter_get_basic(&dict_entry_val, &nrec); - pa_log_debug("nrec= [%d]", nrec); - *is_nrec = nrec; - } + + if (pa_safe_streq("codec", property) && is_wide_band) { + dbus_message_iter_next(&dict_entry); + dbus_message_iter_recurse(&dict_entry, &dict_entry_val); + if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_UINT32) + continue; + dbus_message_iter_get_basic(&dict_entry_val, &codec); + pa_log_debug("Codec = [%d]", codec); + *is_wide_band = (codec == BT_MSBC_CODEC_ID) ? true : false; + } else if (pa_safe_streq("nrec", property) && is_nrec) { + dbus_message_iter_next(&dict_entry); + dbus_message_iter_recurse(&dict_entry, &dict_entry_val); + if (dbus_message_iter_get_arg_type(&dict_entry_val) != DBUS_TYPE_BOOLEAN) + continue; + dbus_message_iter_get_basic(&dict_entry_val, &nrec); + pa_log_debug("nrec= [%d]", nrec); + *is_nrec = nrec; } + dbus_message_iter_next(&reply_iter_entry); } - dbus_message_unref(reply); + return 0; } -- 2.7.4 From a120c0f0c5f15fb2848d1ba7ab6345f9e1e211b3 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Fri, 8 Mar 2019 15:07:33 +0900 Subject: [PATCH 14/16] stream-manager: Add callback for ramp finished [Version] 11.1.34 [Issue type] New feature Change-Id: Ibdf744e79efd08da4c8083f6be2d657a4be7b116 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager-priv.h | 1 + src/stream-manager.c | 21 +++++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 579184a..216a3b9 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.33 +Version: 11.1.34 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager-priv.h b/src/stream-manager-priv.h index 8fc0175..6722e8e 100644 --- a/src/stream-manager-priv.h +++ b/src/stream-manager-priv.h @@ -223,6 +223,7 @@ struct _stream_manager { *sink_input_state_changed_slot, *sink_input_move_start_slot, *sink_input_move_finish_slot, + *sink_input_ramp_finish_slot, *source_output_new_slot, *source_output_put_slot, *source_output_unlink_slot, diff --git a/src/stream-manager.c b/src/stream-manager.c index 0370154..6486172 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -2189,6 +2189,24 @@ static pa_hook_result_t sink_input_move_finish_cb(pa_core *core, pa_sink_input * return PA_HOOK_OK; } +static pa_hook_result_t sink_input_ramp_finish_cb(pa_core *core, pa_sink_input *i, pa_stream_manager *m) { + pa_core_assert_ref(core); + pa_sink_input_assert_ref(i); + + /* There's no point in doing anything if the core is shut down anyway */ + if (core->state == PA_CORE_SHUTDOWN) + return PA_HOOK_OK; + + pa_log_debug("sink-input(%p, index:%u)", i, i->index); + + /* Find a context id from all the ducked stream list by this stream index. + * Check the number of managed streams of the context id, if it is the last one + * then broadcast a signal with context id.*/ + // send_command_signal(pa_dbus_connection_get(m->dbus_conn), "ducking_finished", context_id); + + return PA_HOOK_OK; +} + static pa_hook_result_t source_output_new_cb(pa_core *core, pa_source_output_new_data *new_data, pa_stream_manager *m) { pa_core_assert_ref(core); @@ -3174,6 +3192,7 @@ pa_stream_manager* pa_stream_manager_get(pa_core *c) { m->sink_input_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_state_changed_cb, m); m->sink_input_move_start_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_START], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_move_start_cb, m); m->sink_input_move_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FINISH], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_move_finish_cb, m); + m->sink_input_ramp_finish_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_RAMP_FINISH], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_ramp_finish_cb, m); m->source_output_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_new_cb, m); m->source_output_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_put_cb, m); m->source_output_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_unlink_cb, m); @@ -3257,6 +3276,8 @@ void pa_stream_manager_unref(pa_stream_manager *m) { pa_hook_slot_free(m->sink_input_move_start_slot); if (m->sink_input_move_finish_slot) pa_hook_slot_free(m->sink_input_move_finish_slot); + if (m->sink_input_ramp_finish_slot) + pa_hook_slot_free(m->sink_input_ramp_finish_slot); if (m->source_output_new_slot) pa_hook_slot_free(m->source_output_new_slot); if (m->source_output_put_slot) -- 2.7.4 From ab75d7dc9b85e60db5df599e44dd2ccf9b6dbf16 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Thu, 14 Mar 2019 17:01:11 +0900 Subject: [PATCH 15/16] stream-manager: Consider virtual streams when a device connection is changed Null device of a virtual stream is taken into account in case of the device connection changes. The device of the virtual stream should always be a null device. In addition, the available device defined in stream-map.json for virtual stream type is used to set the audio routing path of internal codec, so these information must propagate to the audio HAL properly. [Version] 11.1.35 [Issue type] Bug fix Change-Id: Idb18334db04ed7d28ca657b1e58a4bb263e6af73 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager.c | 79 +++++++++++++++++++++------------ 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 216a3b9..96f254c 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.34 +Version: 11.1.35 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager.c b/src/stream-manager.c index 6486172..d2f931f 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -946,7 +946,7 @@ static bool check_name_is_vstream(void *stream, stream_type_t type, bool is_new_ if (pa_safe_streq(name, VIRTUAL_STREAM_NAME)) { ret = true; - pa_log_info("name is [%s]", name); + pa_log_debug("name is [%s]", name); } return ret; @@ -2625,9 +2625,13 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_ if ((cur_device_type = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV))) { is_available_device_for_auto_route(m, route_type, cur_device_type, device_type, role, stream_type, &available); if (available) { - pa_sink_input_move_to(s, sink, false); - pa_log_debug(" -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)", - s, ((pa_sink_input*)s)->index, sink, sink->name, device_type); + if (check_name_is_vstream(s, STREAM_SINK_INPUT, false)) { + pa_log_debug(" -- *** keep null sink for a virtual stream"); + } else { + pa_sink_input_move_to(s, sink, false); + pa_log_debug(" -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)", + s, ((pa_sink_input*)s)->index, sink, sink->name, device_type); + } } } else pa_log_error(" -- could not find current device type for s->sink(%p)", ((pa_sink_input*)s)->sink); @@ -2635,9 +2639,13 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_ if ((cur_device_type = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV))) { is_available_device_for_auto_route(m, route_type, cur_device_type, device_type, role, stream_type, &available); if (available) { - pa_source_output_move_to(s, source, false); - pa_log_debug(" -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)", - s, ((pa_source_output*)s)->index, source, source->name, device_type); + if (check_name_is_vstream(s, STREAM_SOURCE_OUTPUT, false)) { + pa_log_debug(" -- *** keep null source for a virtual stream"); + } else { + pa_source_output_move_to(s, source, false); + pa_log_debug(" -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)", + s, ((pa_source_output*)s)->index, source, source->name, device_type); + } } } else pa_log_error(" -- could not find current device type for s->source(%p)", ((pa_source_output*)s)->source); @@ -2651,7 +2659,7 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_ } } else if (!is_connected) { /* DISCONNECTED: find a connected device that has the next priority */ - if ((sink && (sink == ((pa_sink_input*)s)->sink))) { + if (sink && ((sink == ((pa_sink_input*)s)->sink) || check_name_is_vstream(s, STREAM_SINK_INPUT, false))) { if (!is_active_device_of_stream(s, stream_type, device_type)) continue; find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); @@ -2664,10 +2672,14 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_ /* trigger to update routing path if the next device uses internal audio codec */ process_stream_as_device_change_for_auto_route(m, s, stream_type, is_connected, next_device); - pa_sink_input_move_to(s, next_sink, false); - pa_log_debug(" -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)", - s, ((pa_sink_input*)s)->index, next_sink, next_sink->name, new_device_type); + if (check_name_is_vstream(s, STREAM_SINK_INPUT, false)) { + pa_log_debug(" -- *** keep null sink for a virtual stream"); + } else { + pa_sink_input_move_to(s, next_sink, false); + pa_log_debug(" -- *** sink-input(%p,%u) moves to sink(%p,%s), new device(%s)", + s, ((pa_sink_input*)s)->index, next_sink, next_sink->name, new_device_type); } + } } if (!next_device || !next_sink) { @@ -2676,7 +2688,7 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_ s, ((pa_sink_input*)s)->index, null_sink, null_sink->name); } - } else if (source && (source == ((pa_source_output*)s)->source)) { + } else if (source && ((source == ((pa_source_output*)s)->source) || check_name_is_vstream(s, STREAM_SOURCE_OUTPUT, false))) { if (!is_active_device_of_stream(s, stream_type, device_type)) continue; find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); @@ -2690,10 +2702,14 @@ static void update_sink_or_source_as_device_change(pa_stream_manager *m, stream_ if (next_source->use_internal_codec) process_stream_as_device_change_for_auto_route(m, s, stream_type, is_connected, next_device); - pa_source_output_move_to(s, next_source, false); - pa_log_warn(" -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)", - s, ((pa_source_output*)s)->index, next_source, next_source->name, new_device_type); + if (check_name_is_vstream(s, STREAM_SOURCE_OUTPUT, false)) { + pa_log_debug(" -- *** keep null source for a virtual stream"); + } else { + pa_source_output_move_to(s, next_source, false); + pa_log_warn(" -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)", + s, ((pa_source_output*)s)->index, next_source, next_source->name, new_device_type); } + } } if (!next_device || !next_source) { pa_source_output_move_to(s, null_source, false); @@ -2881,6 +2897,8 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi pa_sink *sink = NULL; pa_source *source = NULL; pa_sink_input *si = NULL; + pa_sink_input *highest_prior_si = NULL; + pa_source_output *highest_prior_so = NULL; pa_assert(c); pa_assert(data); @@ -2951,10 +2969,11 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi } /* If the route type is AUTO SERIES, notify again */ - if ((device_direction & DM_DEVICE_DIRECTION_IN) && m->cur_highest_priority.source_output && - !get_route_type(m->cur_highest_priority.source_output, STREAM_SOURCE_OUTPUT, false, &route_type)) { + highest_prior_so = m->cur_highest_priority.source_output; + if ((device_direction & DM_DEVICE_DIRECTION_IN) && highest_prior_so && + !get_route_type(highest_prior_so, STREAM_SOURCE_OUTPUT, false, &route_type)) { if (IS_AUTO_ROUTE_TYPE_SERIES(route_type) && use_internal_codec) { - PA_IDXSET_FOREACH(s, m->cur_highest_priority.source_output->source->outputs, s_idx) { + PA_IDXSET_FOREACH(s, highest_prior_so->source->outputs, s_idx) { if (!data->is_connected && !get_route_type(s, STREAM_SOURCE_OUTPUT, false, &route_type) && ((route_type == STREAM_ROUTE_TYPE_AUTO) || (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED))) { /* remove activated device info. if it has the AUTO route type */ @@ -2963,20 +2982,22 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi pa_proplist_sets(GET_STREAM_PROPLIST(s, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, ACTIVE_DEV_REMOVED); } } - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, false, m->cur_highest_priority.source_output); - if (!((pa_source_output*)(m->cur_highest_priority.source_output))->source->use_internal_codec) { + do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SOURCE_OUTPUT, false, highest_prior_so); + if (!highest_prior_so->source->use_internal_codec && + !check_name_is_vstream(highest_prior_so, STREAM_SOURCE_OUTPUT, false)) { /* If the source of the cur_highest_priority stream uses external codec, it should be updated. * As only the process_stream(PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED) * can update the cur_highest_priority, call it here */ - process_stream(m, m->cur_highest_priority.source_output, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false); + process_stream(m, highest_prior_so, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false); } } } - if ((device_direction & DM_DEVICE_DIRECTION_OUT) && m->cur_highest_priority.sink_input && - !get_route_type(m->cur_highest_priority.sink_input, STREAM_SINK_INPUT, false, &route_type)) { + highest_prior_si = m->cur_highest_priority.sink_input; + if ((device_direction & DM_DEVICE_DIRECTION_OUT) && highest_prior_si && + !get_route_type(highest_prior_si, STREAM_SINK_INPUT, false, &route_type)) { if (IS_AUTO_ROUTE_TYPE_SERIES(route_type) && use_internal_codec) { - PA_IDXSET_FOREACH(s, m->cur_highest_priority.sink_input->sink->inputs, s_idx) { + PA_IDXSET_FOREACH(s, highest_prior_si->sink->inputs, s_idx) { if (!data->is_connected && !get_route_type(s, STREAM_SINK_INPUT, false, &route_type) && ((route_type == STREAM_ROUTE_TYPE_AUTO) || (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED))) { /* remove activated device info. if it has the AUTO route type */ @@ -2985,16 +3006,18 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi pa_proplist_sets(GET_STREAM_PROPLIST(s, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, ACTIVE_DEV_REMOVED); } } - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, m->cur_highest_priority.sink_input); + do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, highest_prior_si); if (((route_type == STREAM_ROUTE_TYPE_AUTO) || (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED)) && - (!((pa_sink_input*)(m->cur_highest_priority.sink_input))->sink->use_internal_codec) && !is_filter_apply_stream(m->cur_highest_priority.sink_input, STREAM_SINK_INPUT)) { + !highest_prior_si->sink->use_internal_codec && + !check_name_is_vstream(highest_prior_si, STREAM_SINK_INPUT, false) && + !is_filter_apply_stream(highest_prior_si, STREAM_SINK_INPUT)) { /* If the sink of the cur_highest_priority stream uses external codec, it should be updated. * As only the process_stream(PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED) * can update the cur_highest_priority, call it here */ - process_stream(m, m->cur_highest_priority.sink_input, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false); + process_stream(m, highest_prior_si, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false); } } else if (route_type == STREAM_ROUTE_TYPE_AUTO_ALL) - do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, m->cur_highest_priority.sink_input); + do_notify(m, NOTIFY_COMMAND_CHANGE_ROUTE_START, STREAM_SINK_INPUT, false, highest_prior_si); } if (m->on_call) { -- 2.7.4 From b2cd2a0deea5e77673f10b4a7b22e3d413cd70a6 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Mon, 25 Mar 2019 17:49:41 +0900 Subject: [PATCH 16/16] stream-manager-volume: Revise codes to improve readability [Version] 11.1.36 [Issue type] Refactoring Change-Id: Ieb917f9e6b7b068cd934304bc923cb86bac35615 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager-volume.c | 52 ++++++++++++++++----------------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 96f254c..bb0b593 100644 --- a/packaging/pulseaudio-modules-tizen.spec +++ b/packaging/pulseaudio-modules-tizen.spec @@ -1,6 +1,6 @@ Name: pulseaudio-modules-tizen Summary: Pulseaudio modules for Tizen -Version: 11.1.35 +Version: 11.1.36 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager-volume.c b/src/stream-manager-volume.c index db3c4b7..99beaeb 100644 --- a/src/stream-manager-volume.c +++ b/src/stream-manager-volume.c @@ -309,6 +309,7 @@ int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type } if (!pa_safe_streq(volume_type, MASTER_VOLUME_TYPE)) { + /* Get volume value */ if (get_volume_value(m, stream_type, is_hal_volume, volume_type, volume_level, &volume_linear)) return -1; @@ -316,53 +317,50 @@ int32_t set_volume_level_by_type(pa_stream_manager *m, stream_type_t stream_type if (!(volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) continue; + /* Update volume level of stream if it has requested the volume type */ + if (!pa_safe_streq(volume_type_str, volume_type)) + continue; + /* Get modifier for gain */ modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); - - /* Update volume level of stream if it has requested the volume type */ - if (pa_safe_streq(volume_type_str, volume_type)) { - if (modifier_gain) { - if (m->volume_modifiers) { - if ((modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain))) { - volume_linear *= (*modifier_gain_value); - pa_log_info("apply the modifier for the gain value[%s=>%f], result volume_linear[%f]", - modifier_gain, *modifier_gain_value, volume_linear); - } - } + if (modifier_gain && m->volume_modifiers) { + if ((modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain))) { + volume_linear *= (*modifier_gain_value); + pa_log_info("apply the modifier for the gain value[%s=>%f], result volume_linear[%f]", + modifier_gain, *modifier_gain_value, volume_linear); } - pa_cvolume_set(&cv, GET_STREAM_SAMPLE_SPEC(s, stream_type).channels, pa_sw_volume_from_linear(volume_linear)); - if (stream_type == STREAM_SINK_INPUT) - pa_sink_input_set_volume((pa_sink_input*)s, &cv, true, true); - else if (stream_type == STREAM_SOURCE_OUTPUT) - pa_source_output_set_volume((pa_source_output*)s, &cv, true, true); } + + pa_cvolume_set(&cv, GET_STREAM_SAMPLE_SPEC(s, stream_type).channels, pa_sw_volume_from_linear(volume_linear)); + if (stream_type == STREAM_SINK_INPUT) + pa_sink_input_set_volume((pa_sink_input*)s, &cv, true, true); + else if (stream_type == STREAM_SOURCE_OUTPUT) + pa_source_output_set_volume((pa_source_output*)s, &cv, true, true); } } else { PA_IDXSET_FOREACH(s, stream_type == STREAM_SINK_INPUT ? m->core->sink_inputs : m->core->source_outputs, idx) { if (!(volume_type_str = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_TYPE))) continue; - /* Get modifier for gain */ - modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); - /* Get volume level of this type */ if (!(v = pa_hashmap_get(volumes, volume_type_str))) continue; - volume_level = v->values[stream_type].current_level; + /* Get volume value */ if (get_volume_value(m, stream_type, is_hal_volume, volume_type_str, volume_level, &volume_linear)) continue; - if (modifier_gain) { - if (m->volume_modifiers) { - if ((modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain))) { - volume_linear *= (*modifier_gain_value); - pa_log_info("set_volume_level_by_type() : apply the modifier for the gain value[%s=>%f], result volume_linear[%f]", - modifier_gain, *modifier_gain_value, volume_linear); - } + /* Get modifier for gain */ + modifier_gain = pa_proplist_gets(GET_STREAM_PROPLIST(s, stream_type), PA_PROP_MEDIA_TIZEN_VOLUME_GAIN_TYPE); + if (modifier_gain && m->volume_modifiers) { + if ((modifier_gain_value = pa_hashmap_get(m->volume_modifiers, modifier_gain))) { + volume_linear *= (*modifier_gain_value); + pa_log_info("set_volume_level_by_type() : apply the modifier for the gain value[%s=>%f], result volume_linear[%f]", + modifier_gain, *modifier_gain_value, volume_linear); } } + pa_cvolume_set(&cv, GET_STREAM_SAMPLE_SPEC(s, stream_type).channels, pa_sw_volume_from_linear(volume_linear)); if (stream_type == STREAM_SINK_INPUT) pa_sink_input_set_volume((pa_sink_input*)s, &cv, true, true); -- 2.7.4