From ad42f10de6cfdc7d09464738af0a03327d0d7b8f Mon Sep 17 00:00:00 2001 From: Mok Jeongho Date: Fri, 23 Sep 2016 16:07:06 +0900 Subject: [PATCH 01/16] device-manager : Add Interface to load forwarding device [Version] 5.0.78 [Profile] Common [Issue Type] Feature Change-Id: Icf7ee44fb45dbf34188e889794b8e83b6cac0010 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 71 ++++++++++++++++++++++++--------- src/device-manager.h | 4 ++ 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index c7b62d7..ab20110 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: 5.0.77 +Version: 5.0.78 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index 81ed0c2..3cbd7c9 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -1820,6 +1820,43 @@ static int _load_type_devices(struct device_type_info *type_info, bool is_playba return 0; } +static pa_tz_device* _load_forwarding_device(pa_device_manager *dm) { + pa_tz_device_new_data data; + pa_tz_device *spk_device, *forwarding_device; + pa_sink *spk_sink; + + pa_assert(dm); + + pa_log_info("Load forwarding device"); + + 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) { + pa_log_error("Get speaker device failed"); + return NULL; + } + + if ((spk_sink = pa_tz_device_get_sink(spk_device, DEVICE_ROLE_NORMAL)) == NULL) { + pa_log_error("Get speaker sink failed"); + return NULL; + } + + pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL); + _fill_new_data_basic(&data, DEVICE_TYPE_FORWARDING, DM_DEVICE_DIRECTION_BOTH, true, dm); + pa_tz_device_new_data_add_sink(&data, DEVICE_ROLE_NORMAL, spk_sink); + pa_tz_device_new_data_add_source(&data, DEVICE_ROLE_NORMAL, spk_sink->monitor_source); + + if ((forwarding_device = pa_tz_device_new(&data)) == NULL) + pa_log_error("Failed to create forwarding device"); + + pa_tz_device_new_data_done(&data); + + return forwarding_device; +} + /* Handle device connection detected through dbus. First, update device-status hashmap. @@ -1891,25 +1928,7 @@ static void handle_device_connected(pa_device_manager *dm, const char *type, con pa_tz_device_new(&data); pa_tz_device_new_data_done(&data); } else if (device_type_is_equal(type, device_profile, DEVICE_TYPE_FORWARDING, NULL)) { - pa_tz_device *spk_device; - pa_sink *spk_sink; - - if (!(spk_device = _device_list_get_device(dm, DEVICE_TYPE_SPEAKER, NULL))) { - pa_log_error("Get speaker device failed"); - return; - } - if (!(spk_sink = pa_tz_device_get_sink(spk_device, DEVICE_ROLE_NORMAL))) { - pa_log_error("Get speaker sink failed"); - return; - } - - pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL); - _fill_new_data_basic(&data, DEVICE_TYPE_FORWARDING, DM_DEVICE_DIRECTION_BOTH, true, dm); - pa_tz_device_new_data_add_sink(&data, DEVICE_ROLE_NORMAL, spk_sink); - pa_tz_device_new_data_add_source(&data, DEVICE_ROLE_NORMAL, spk_sink->monitor_source); - - pa_tz_device_new(&data); - pa_tz_device_new_data_done(&data); + _load_forwarding_device(dm); } else { dm_device_direction_t direction; @@ -3049,6 +3068,20 @@ pa_tz_device* pa_device_manager_get_device_with_source(pa_source *source) { return source->device_item; } +pa_tz_device* pa_device_manager_load_forwarding(pa_device_manager *dm) { + return _load_forwarding_device(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); + if (forwarding_device) + pa_tz_device_free(forwarding_device); + else + pa_log_warn("There is no forwarding device"); +} + int pa_device_manager_load_sink(pa_device_manager *dm, const char *type, const char *device_profile, const char *role) { const char *device_string, *params; struct device_type_info *type_info; diff --git a/src/device-manager.h b/src/device-manager.h index 8e2c04d..12abeeb 100644 --- a/src/device-manager.h +++ b/src/device-manager.h @@ -44,6 +44,10 @@ pa_tz_device* pa_device_manager_get_device_by_id(pa_device_manager *dm, uint32_t pa_tz_device* pa_device_manager_get_device_with_sink(pa_sink *sink); pa_tz_device* pa_device_manager_get_device_with_source(pa_source *source); +/* trigger for create/destroy forwarding device */ +pa_tz_device* pa_device_manager_load_forwarding(pa_device_manager *dm); +void pa_device_manager_unload_forwarding(pa_device_manager *dm); + /* load pulse device */ int pa_device_manager_load_sink(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role); int pa_device_manager_load_source(pa_device_manager *dm, const char *device_type, const char *device_profile, const char *role); -- 2.7.4 From 552793701f14d810cd827ca6cbc5cfc1ce6efc1f Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Mon, 26 Sep 2016 14:55:56 +0900 Subject: [PATCH 02/16] Use absolute path for audio-hal dlopen to avoid malicious attack [Version] 5.0.79 [Profile] Common [Issue Type] Security Change-Id: I5ce2acd3ae5efe8a139b7a5d3efa8c039fe96ed5 --- packaging/pulseaudio-modules-tizen.spec | 4 ++-- src/hal-interface.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index ab20110..64232a4 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: 5.0.78 +Version: 5.0.79 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ @@ -32,7 +32,7 @@ This package contains pulseaudio modules for tizen audio system. %setup -q %build -export CFLAGS="%{optflags} -fno-strict-aliasing -DSYSCONFDIR=\\\"%{_sysconfdir}\\\"" +export CFLAGS="%{optflags} -fno-strict-aliasing -DSYSCONFDIR=\\\"%{_sysconfdir}\\\" -DAUDIOHALDIR=\\\"%{_libdir}\\\"" export LD_AS_NEEDED=0 %reconfigure --prefix=%{_prefix} \ diff --git a/src/hal-interface.c b/src/hal-interface.c index f7ef786..80d3408 100644 --- a/src/hal-interface.c +++ b/src/hal-interface.c @@ -30,7 +30,7 @@ #define SHARED_HAL_INTF "tizen-hal-interface" /* Audio HAL library */ -#define LIB_TIZEN_AUDIO "libtizen-audio.so" +#define LIB_TIZEN_AUDIO AUDIOHALDIR"/libtizen-audio.so" struct _pa_hal_interface { PA_REFCNT_DECLARE; -- 2.7.4 From 49136f7a49cb6f463f5ce8f13ee6ca17f5d8af4e Mon Sep 17 00:00:00 2001 From: Mok Jeongho Date: Thu, 1 Sep 2016 19:33:43 +0900 Subject: [PATCH 03/16] device-manager : avail-mode for bt [Version] 5.0.80 [Profile] Common [Issue Type] API Change-Id: Iab8597b1eefde9f8f31eff69cc144d86a5d70c30 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/communicator.h | 3 +- src/device-manager.c | 96 +++++++++++++++++++++++---------- src/module-tizenaudio-policy.c | 22 ++++---- src/stream-manager.c | 2 +- src/subscribe-observer.c | 2 +- src/subscribe-observer.h | 2 +- src/tizen-device-def.h | 5 -- src/tizen-device.c | 48 ++++++++++------- src/tizen-device.h | 22 ++++++-- 10 files changed, 134 insertions(+), 70 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 64232a4..24dda5e 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: 5.0.79 +Version: 5.0.80 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/communicator.h b/src/communicator.h index 8f75be8..849c6be 100644 --- a/src/communicator.h +++ b/src/communicator.h @@ -28,7 +28,8 @@ typedef enum pa_communicator_hook { PA_COMMUNICATOR_HOOK_SELECT_INIT_SINK_OR_SOURCE, /* It is fired when a stream is created and needs to be set to sink or source */ PA_COMMUNICATOR_HOOK_CHANGE_ROUTE, /* It is fired when routing using internal codec should be processed */ PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED, /* It is fired when a device is connected or disconnected */ - PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED, /* It is fired when a device's property is changed */ + PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED, /* It is fired when a device's profile is changed */ + PA_COMMUNICATOR_HOOK_DEVICE_STATE_CHANGED, /* It is fired when a device's state is changed */ PA_COMMUNICATOR_HOOK_EVENT_FULLY_HANDLED, /* It is fired when a event is handled by all subscribers */ PA_COMMUNICATOR_HOOK_UPDATE_INFORMATION, /* It is fired when information should be updated */ PA_COMMUNICATOR_HOOK_MAX diff --git a/src/device-manager.c b/src/device-manager.c index 3cbd7c9..f0f3b96 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -112,7 +112,7 @@ " \n" \ " \n" \ " \n" \ - " \n" \ + " \n" \ " \n" \ " " \ " " \ @@ -285,6 +285,18 @@ typedef enum { 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 +} dm_device_bt_mode_t; + +typedef enum dm_device_changed_into_type { + DM_DEVICE_CHANGED_INFO_STATE, + DM_DEVICE_CHANGED_INFO_IO_DIRECTION, + DM_DEVICE_CHANGED_INFO_BT_AVAIL_MODE, + DM_DEVICE_CHANGED_INFO_MAX +} dm_device_changed_info_t; + /* Structure to save parsed information about device-file. @@ -353,7 +365,8 @@ struct pa_device_manager { pa_core *core; pa_hook_slot *sink_put_hook_slot, *sink_state_changed_slot, *sink_unlink_hook_slot; pa_hook_slot *source_put_hook_slot, *source_state_changed_slot, *source_unlink_hook_slot; - pa_hook_slot *comm_hook_device_connection_changed_slot, *comm_hook_device_info_changed_slot; + pa_hook_slot *comm_hook_device_connection_changed_slot, *comm_hook_device_profile_changed_slot; + pa_hook_slot *comm_hook_device_state_changed_slot; pa_communicator *comm; /* @@ -415,14 +428,6 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { .receive_cb = handle_test_device_status_change}, }; -/*** Defines for signal send ***/ - -enum signal_index { - SIGNAL_DEVICE_CONNECTED, - SIGNAL_DEVICE_INFO_CHANGED, - SIGNAL_MAX -}; - #endif static void type_info_free_func(struct device_type_info *type_info) { @@ -1503,7 +1508,7 @@ static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *sourc -static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *pdevice, pa_device_manager *dm) { +static pa_hook_result_t sink_source_state_changed_hook_cb(pa_core *c, pa_object *pdevice, pa_device_manager *dm) { pa_tz_device *device; bool use_internal_codec = false; uint32_t idx = 0; @@ -1553,7 +1558,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *pdev } } } - pa_log_debug("========= device_state_changed_hook_cb END ====="); + pa_log_debug("========= sink_source_state_changed_hook_cb END ====="); return PA_HOOK_OK; } @@ -2592,19 +2597,39 @@ static void unwatch_signals(pa_device_manager *dm) { dbus_connection_remove_filter(pa_dbus_connection_get(dm->dbus_conn), dbus_filter_device_detect_handler, dm); } +static int _get_avail_mode(pa_tz_device *device) { + int avail_mode = 0; + char *type; + + pa_assert(device); + + type = pa_tz_device_get_type(device); + if (pa_streq(type, DEVICE_TYPE_BT) == false) { + pa_log_debug("Not BT device"); + return 0; + } + + if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_SCO)) + avail_mode |= DM_DEVICE_BT_MODE_VOICE; + if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_A2DP)) + avail_mode |= DM_DEVICE_BT_MODE_MEDIA; + + return avail_mode; +} static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) { DBusMessage *signal_msg; DBusMessageIter msg_iter, device_iter; dbus_bool_t _connected = connected; dm_device_state_t compound_state; - dbus_int32_t device_id, direction; + dbus_int32_t device_id, direction, avail_mode; char *type, *name; pa_assert(device); pa_assert(dm); - pa_log_info("Send following device %s signal", connected ? "Connected" : "Disconnected"); + pa_log_info("Send device %s signal, event_id(%u) device(%u)", + connected ? "Connected" : "Disconnected", event_id, device->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); @@ -2614,6 +2639,7 @@ static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device direction = (dbus_int32_t) pa_tz_device_get_direction(device); type = pa_tz_device_get_type(device); name = pa_tz_device_get_name(device); + avail_mode = _get_avail_mode(device); device_id = (dbus_int32_t) pa_tz_device_get_id(device); compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); @@ -2621,6 +2647,7 @@ static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device 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, &compound_state); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &avail_mode); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter)); dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_BOOLEAN, &_connected); @@ -2634,13 +2661,14 @@ static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *dev DBusMessage *signal_msg; DBusMessageIter msg_iter, device_iter; dm_device_state_t compound_state; - dbus_int32_t device_id, direction; + dbus_int32_t device_id, direction, avail_mode; char *type, *name; pa_assert(device); pa_assert(dm); - pa_log_debug("Send following device info changed signal"); + pa_log_debug("Send device info changed signal, event_id(%u) device(%u) changed_type(%d)", + event_id, device->id, changed_type); 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); @@ -2652,11 +2680,13 @@ static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *dev name = pa_tz_device_get_name(device); device_id = (dbus_int32_t) pa_tz_device_get_id(device); compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); + avail_mode = (dbus_int32_t) _get_avail_mode(device); 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, &compound_state); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &avail_mode); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); pa_assert_se(dbus_message_iter_close_container(&msg_iter, &device_iter)); dbus_message_iter_append_basic(&msg_iter, DBUS_TYPE_INT32, &changed_type); @@ -2767,7 +2797,7 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * pa_tz_device *device; dm_device_state_t compound_state; uint32_t device_idx; - dbus_int32_t device_id, direction; + dbus_int32_t device_id, direction, avail_mode; int mask_flags; char *type, *name; @@ -2786,13 +2816,14 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * DBUS_TYPE_INVALID)); dbus_message_iter_init_append(reply, &msg_iter); - pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiis)", &array_iter)); + pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(isiiis)", &array_iter)); PA_IDXSET_FOREACH(device, dm->device_list, device_idx) { compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); direction = pa_tz_device_get_direction(device); type = pa_tz_device_get_type(device); name = pa_tz_device_get_name(device); + avail_mode = _get_avail_mode(device); if (device_item_match_for_mask(device, mask_flags, dm)) { device_id = (dbus_int32_t)pa_tz_device_get_id(device); pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &device_iter)); @@ -2800,6 +2831,7 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * 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, &compound_state); + dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &avail_mode); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); pa_assert_se(dbus_message_iter_close_container(&array_iter, &device_iter)); } @@ -3200,13 +3232,19 @@ fail: return -1; } -static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *data, pa_device_manager *dm) { +static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *data, pa_device_manager *dm) { send_device_connected_signal(data->event_id, data->device, data->is_connected, dm); return PA_HOOK_OK; } -static pa_hook_result_t device_info_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_info_changed *data, pa_device_manager *dm) { - send_device_info_changed_signal(data->event_id, data->device, data->changed_info, dm); +static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_profile_changed *data, pa_device_manager *dm) { + if (data->changed == PA_TZ_DEVICE_PROFILE_ADDED || data->changed == PA_TZ_DEVICE_PROFILE_REMOVED) + send_device_info_changed_signal(data->event_id, data->device, DM_DEVICE_CHANGED_INFO_BT_AVAIL_MODE, dm); + return PA_HOOK_OK; +} + +static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_state_changed *data, pa_device_manager *dm) { + send_device_info_changed_signal(data->event_id, data->device, DM_DEVICE_CHANGED_INFO_STATE, dm); return PA_HOOK_OK; } @@ -3229,16 +3267,18 @@ pa_device_manager* pa_device_manager_get(pa_core *c) { dbus_init(dm); dm->sink_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_put_hook_callback, dm); - dm->sink_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) device_state_changed_hook_cb, dm); + dm->sink_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_source_state_changed_hook_cb, dm); dm->sink_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) sink_unlink_hook_callback, dm); dm->source_put_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+10, (pa_hook_cb_t) source_put_hook_callback, dm); - dm->source_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) device_state_changed_hook_cb, dm); + dm->source_state_changed_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_source_state_changed_hook_cb, dm); dm->source_unlink_hook_slot = pa_hook_connect(&dm->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_EARLY, (pa_hook_cb_t) source_unlink_hook_callback, dm); dm->comm = pa_communicator_get(dm->core); dm->comm_hook_device_connection_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), PA_HOOK_EARLY, (pa_hook_cb_t)device_connection_changed_hook_cb, dm); - dm->comm_hook_device_info_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), - PA_HOOK_EARLY, (pa_hook_cb_t)device_info_changed_hook_cb, dm); + dm->comm_hook_device_profile_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED), + PA_HOOK_EARLY, (pa_hook_cb_t)device_profile_changed_hook_cb, dm); + dm->comm_hook_device_state_changed_slot = pa_hook_connect(pa_communicator_hook(dm->comm, PA_COMMUNICATOR_HOOK_DEVICE_STATE_CHANGED), + PA_HOOK_EARLY, (pa_hook_cb_t)device_state_changed_hook_cb, dm); if (!(dm->type_infos = parse_device_type_infos())) { pa_log_error("Parse device-type-map failed"); return NULL; @@ -3289,8 +3329,10 @@ void pa_device_manager_unref(pa_device_manager *dm) { if (dm->comm_hook_device_connection_changed_slot) pa_hook_slot_free(dm->comm_hook_device_connection_changed_slot); - if (dm->comm_hook_device_info_changed_slot) - pa_hook_slot_free(dm->comm_hook_device_info_changed_slot); + if (dm->comm_hook_device_profile_changed_slot) + pa_hook_slot_free(dm->comm_hook_device_profile_changed_slot); + if (dm->comm_hook_device_state_changed_slot) + pa_hook_slot_free(dm->comm_hook_device_state_changed_slot); if (dm->sink_put_hook_slot) pa_hook_slot_free(dm->sink_put_hook_slot); if (dm->sink_state_changed_slot) diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index fe46d7a..51456c6 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -156,7 +156,7 @@ struct userdata { pa_hook_slot *comm_hook_select_proper_sink_or_source_slot; pa_hook_slot *comm_hook_change_route_slot; pa_hook_slot *comm_hook_device_connection_changed_slot; - pa_hook_slot *comm_hook_device_info_changed_slot; + pa_hook_slot *comm_hook_device_profile_changed_slot; pa_hook_slot *comm_hook_update_info_slot; } communicator; @@ -1130,7 +1130,7 @@ static void dump_connected_devices() } /* Reorganize routing when a device has been connected or disconnected */ -static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *conn, struct userdata *u) { +static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *conn, struct userdata *u) { uint32_t idx = 0; pa_sink_input *s = NULL; dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT; @@ -1223,7 +1223,7 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_ } /* Update connected device list when a device's information has been changed */ -static pa_hook_result_t device_info_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_info_changed *conn, struct userdata *u) { +static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_profile_changed *conn, struct userdata *u) { dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT; int* ptr_in = NULL; int* ptr_out = NULL; @@ -1234,10 +1234,10 @@ static pa_hook_result_t device_info_changed_hook_cb(pa_core *c, pa_device_manage device_direction = pa_tz_device_get_direction(conn->device); - pa_log_info("[CONN] device_info_changed_hook_cb is called. conn(%p), changed_info(%d), device(%p), direction(0x%x)", - conn, conn->changed_info, conn->device, device_direction); + pa_log_info("[CONN] device_profile_changed_hook_cb is called. conn(%p), changed(%d), device(%p), direction(0x%x)", + conn, conn->changed, conn->device, device_direction); - if (conn->changed_info == DM_DEVICE_CHANGED_INFO_IO_DIRECTION) + if (conn->changed == PA_TZ_DEVICE_ACTIVE_PROFILE_CHANGED) if (pa_streq(pa_tz_device_get_type(conn->device), DEVICE_TYPE_BT)) { /* In case of the bluetooth, we do not maintain a ref. count of the bluetooth devices. * Because bluetooth framework supports only one device simultaneously for audio profile. */ @@ -1283,9 +1283,9 @@ int pa__init(pa_module *m) u->communicator.comm_hook_device_connection_changed_slot = pa_hook_connect( pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), PA_HOOK_EARLY, (pa_hook_cb_t)device_connection_changed_hook_cb, u); - u->communicator.comm_hook_device_info_changed_slot = pa_hook_connect( - pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), - PA_HOOK_EARLY, (pa_hook_cb_t)device_info_changed_hook_cb, u); + u->communicator.comm_hook_device_profile_changed_slot = pa_hook_connect( + pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED), + PA_HOOK_EARLY, (pa_hook_cb_t)device_profile_changed_hook_cb, u); u->communicator.comm_hook_update_info_slot = pa_hook_connect( pa_communicator_hook(u->communicator.comm, PA_COMMUNICATOR_HOOK_UPDATE_INFORMATION), PA_HOOK_EARLY, (pa_hook_cb_t)update_info_hook_cb, u); @@ -1344,8 +1344,8 @@ void pa__done(pa_module *m) pa_hook_slot_free(u->communicator.comm_hook_change_route_slot); if (u->communicator.comm_hook_device_connection_changed_slot) pa_hook_slot_free(u->communicator.comm_hook_device_connection_changed_slot); - if (u->communicator.comm_hook_device_info_changed_slot) - pa_hook_slot_free(u->communicator.comm_hook_device_info_changed_slot); + if (u->communicator.comm_hook_device_profile_changed_slot) + pa_hook_slot_free(u->communicator.comm_hook_device_profile_changed_slot); if (u->communicator.comm_hook_update_info_slot) pa_hook_slot_free(u->communicator.comm_hook_update_info_slot); pa_communicator_unref(u->communicator.comm); diff --git a/src/stream-manager.c b/src/stream-manager.c index a356637..13b80eb 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3309,7 +3309,7 @@ static pa_hook_result_t event_fully_handled_hook_cb(pa_core *c, pa_subscribe_obs } /* Reorganize routing when a device has been connected or disconnected */ -static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *data, pa_stream_manager *m) { +static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *data, pa_stream_manager *m) { const char *active_dev = NULL; const char *device_type = NULL; stream_route_type_t route_type; diff --git a/src/subscribe-observer.c b/src/subscribe-observer.c index 9e6c8df..7b13092 100644 --- a/src/subscribe-observer.c +++ b/src/subscribe-observer.c @@ -623,7 +623,7 @@ static void dbus_deinit(pa_subscribe_observer *ob) { } } -static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_device_manager_hook_data_for_conn_changed *data, pa_subscribe_observer *ob) { +static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *data, pa_subscribe_observer *ob) { struct event *new_event; pa_idxset *handled_subscribers; diff --git a/src/subscribe-observer.h b/src/subscribe-observer.h index 6210963..96b538f 100644 --- a/src/subscribe-observer.h +++ b/src/subscribe-observer.h @@ -41,7 +41,7 @@ typedef enum pa_tizen_event_type { typedef struct _hook_data_for_event_handled { /* Unique id of event, you can determine what event this is about * by comparing this with real event's id. - * For example, event_id of pa_device_manager_hook_data_for_conn_changed */ + * For example, event_id of pa_tz_device_hook_data_for_conn_changed */ uint32_t event_id; pa_tizen_event_t event_type; } pa_subscribe_observer_hook_data_for_event_handled; diff --git a/src/tizen-device-def.h b/src/tizen-device-def.h index e4efdd7..dedebdf 100644 --- a/src/tizen-device-def.h +++ b/src/tizen-device-def.h @@ -33,11 +33,6 @@ typedef enum dm_device_direction_type { DM_DEVICE_DIRECTION_BOTH = DM_DEVICE_DIRECTION_IN | DM_DEVICE_DIRECTION_OUT } dm_device_direction_t; -typedef enum dm_device_changed_into_type { - DM_DEVICE_CHANGED_INFO_STATE, - DM_DEVICE_CHANGED_INFO_IO_DIRECTION -} dm_device_changed_info_t; - typedef enum dm_device_state_type { DM_DEVICE_STATE_DEACTIVATED = 0, DM_DEVICE_STATE_ACTIVATED diff --git a/src/tizen-device.c b/src/tizen-device.c index 7f90121..2eabac8 100644 --- a/src/tizen-device.c +++ b/src/tizen-device.c @@ -133,33 +133,41 @@ void pa_tz_device_dump_info(pa_tz_device *device, pa_log_level_t log_level) { } static void notify_device_connection_changed(pa_tz_device *device, bool connected) { - pa_device_manager_hook_data_for_conn_changed hook_data; - uint32_t event_id; + pa_tz_device_hook_data_for_conn_changed hook_data; - event_id = _new_event_id(); - - hook_data.event_id = event_id; + hook_data.event_id = _new_event_id(); hook_data.is_connected = connected; hook_data.device = device; - pa_log_info("Fire hook for device connection changed, device(%u) %s", - device->id, connected ? "connected" : "disconnected"); + pa_log_info("Fire hook for device connection changed, device(%s/%u) %s", + device->type, device->id, connected ? "connected" : "disconnected"); pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), &hook_data); } -static void notify_device_info_changed(pa_tz_device *device, dm_device_changed_info_t changed_type) { - pa_device_manager_hook_data_for_info_changed hook_data; - uint32_t event_id; +static void notify_device_profile_changed(pa_tz_device *device, pa_tz_device_profile_changed_t changed_type) { + pa_tz_device_hook_data_for_profile_changed hook_data; + const char* changed_type_str[PA_TZ_DEVICE_PROFILE_CHANGED_MAX] = + {"Profile Added", "Profile Removed", "Active-profile Changed"}; + + hook_data.event_id = _new_event_id(); + hook_data.changed = changed_type; + hook_data.device = device; + + pa_log_info("Fire hook for device profile changed, device(%s/%u) %s", + device->type, device->id, changed_type_str[changed_type]); + pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED), &hook_data); +} - event_id = _new_event_id(); +static void notify_device_state_changed(pa_tz_device *device, dm_device_state_t state) { + pa_tz_device_hook_data_for_state_changed hook_data; - hook_data.event_id = event_id; - hook_data.changed_info = changed_type; + hook_data.event_id = _new_event_id(); + hook_data.activated = (state == DM_DEVICE_STATE_ACTIVATED) ? true : false; hook_data.device = device; - pa_log_info("Fire hook for device info changed, device(%u) %s changed", - device->id, changed_type == DM_DEVICE_CHANGED_INFO_STATE ? "state" : "direction"); - pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_INFORMATION_CHANGED), &hook_data); + pa_log_info("Fire hook for device state changed, device(%s/%u) %s", + device->type, device->id, hook_data.activated ? "Activated" : "De-activated"); + pa_hook_fire(pa_communicator_hook(device->comm, PA_COMMUNICATOR_HOOK_DEVICE_STATE_CHANGED), &hook_data); } /* pa_tz_device_new_data */ @@ -371,7 +379,7 @@ static void profile_set_state(pa_tz_profile *profile, dm_device_direction_t dire pa_log_debug("new playback_state : %d, capture_state : %d => state %d", profile->playback_state, profile->capture_state, new_state); if (prev_state != new_state) { - notify_device_info_changed(profile->device, DM_DEVICE_CHANGED_INFO_STATE); + notify_device_state_changed(profile->device, new_state); pa_tz_device_dump_info(profile->device, PA_LOG_DEBUG); } } @@ -583,7 +591,7 @@ int _set_active_profile(pa_tz_device *device, const char *profile, bool noti_alw /* Compare index only when check_idx is true */ if (noti_always || prev_active_idx != device->active_profile) - notify_device_info_changed(device, DM_DEVICE_CHANGED_INFO_IO_DIRECTION); + notify_device_profile_changed(device, PA_TZ_DEVICE_ACTIVE_PROFILE_CHANGED); return 0; } @@ -613,6 +621,7 @@ int pa_tz_device_add_profile(pa_tz_device *device, pa_tz_profile_new_data *pdata if (as_active) _set_active_profile(device, pdata->profile, true); + notify_device_profile_changed(device, PA_TZ_DEVICE_PROFILE_ADDED); pa_tz_device_dump_info(device, PA_LOG_INFO); return 0; @@ -653,6 +662,7 @@ int pa_tz_device_remove_profile(pa_tz_device *device, const char *profile_str) { /* change active profile if removed one was active */ if (device->active_profile == remove_idx) _set_active_profile(device, NULL, true); + notify_device_profile_changed(device, PA_TZ_DEVICE_PROFILE_REMOVED); pa_tz_device_dump_info(device, PA_LOG_INFO); return 0; } else { @@ -1056,6 +1066,8 @@ pa_source* pa_tz_device_get_source(pa_tz_device *device, const char *role) { return source; } +/* TODO : Change param dm_device_state_t to bool or pa_tz_device_state_t, + * Because this state represent pa_tz_device's own state */ void pa_tz_device_set_state(pa_tz_device *device, dm_device_direction_t direction, dm_device_state_t state) { pa_tz_profile *profile; diff --git a/src/tizen-device.h b/src/tizen-device.h index 9cd4f75..0776c98 100644 --- a/src/tizen-device.h +++ b/src/tizen-device.h @@ -9,6 +9,13 @@ #include #endif +typedef enum pa_tz_device_profile_changed_type { + PA_TZ_DEVICE_PROFILE_ADDED, + PA_TZ_DEVICE_PROFILE_REMOVED, + PA_TZ_DEVICE_ACTIVE_PROFILE_CHANGED, + PA_TZ_DEVICE_PROFILE_CHANGED_MAX +} pa_tz_device_profile_changed_t; + typedef struct pa_tz_device pa_tz_device; typedef struct pa_tz_profile pa_tz_profile; typedef struct pa_tz_device_new_data pa_tz_device_new_data; @@ -122,13 +129,19 @@ typedef struct _hook_call_data_for_conn_changed { uint32_t event_id; bool is_connected; pa_tz_device *device; -} pa_device_manager_hook_data_for_conn_changed; +} pa_tz_device_hook_data_for_conn_changed; + +typedef struct _hook_call_data_for_profile_changed { + uint32_t event_id; + pa_tz_device_profile_changed_t changed; + pa_tz_device *device; +} pa_tz_device_hook_data_for_profile_changed; -typedef struct _hook_call_data_for_info_changed { +typedef struct _hook_call_data_for_state_changed { uint32_t event_id; - dm_device_changed_info_t changed_info; + bool activated; pa_tz_device *device; -} pa_device_manager_hook_data_for_info_changed; +} pa_tz_device_hook_data_for_state_changed; /*** For device manager ***/ void pa_tz_device_dump_info(pa_tz_device *device, pa_log_level_t log_level); @@ -196,6 +209,7 @@ pa_usec_t pa_tz_device_get_creation_time(pa_tz_device *device); bool pa_tz_device_is_use_internal_codec(pa_tz_device *device); unsigned pa_tz_device_get_profile_num(pa_tz_device *device); bool pa_tz_device_have_profile(pa_tz_device *device, const char *profile); +int pa_tz_device_get_bt_avail_mode(pa_tz_device *device); /* Only for BT device * Check device type and check also sco profile -- 2.7.4 From f76ce81102cd303efd709d150625ac0787b5cbe9 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 27 Sep 2016 15:59:07 +0900 Subject: [PATCH 04/16] stream-manager: Support loopback-mirroring stream type and add logics to load/unload forwarding device [Version] 5.0.81 [Profile] Common [Issue Type] Feature enhancement Change-Id: I70a93307b3d85c727c5d6bb8443e7ec0a76bdcdd Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-policy.c | 240 ++++++++++++++++---------------- src/stream-manager-priv.h | 1 + src/stream-manager-volume.c | 4 - src/stream-manager.c | 109 +++++++++------ src/stream-manager.h | 19 +-- 6 files changed, 199 insertions(+), 176 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 24dda5e..3a6a20f 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: 5.0.80 +Version: 5.0.81 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index 51456c6..b3976e6 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -208,6 +208,121 @@ static void __load_dump_config(struct userdata *u) } } +/* The state of a device using internal audio codec is handled here. + * Regarding the state of an external device, it is handled in device-manager.c */ +static void set_device_state_if_using_internal_codec(pa_tz_device *device, stream_type_t stream_type, dm_device_state_t device_state) { + dm_device_direction_t direction; + + pa_assert(device); + + direction = pa_tz_device_get_direction(device); + if (IS_AVAILABLE_DIRECTION(stream_type, direction)) + if (pa_tz_device_is_use_internal_codec(device)) + pa_tz_device_set_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state); +} + +/* threre is only one sco connected device */ +static pa_tz_device* _get_sco_connected_device(pa_device_manager *dm) { + pa_idxset *device_list; + pa_tz_device *device; + uint32_t device_idx; + + pa_assert(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)) { + /* FIXME : not works */ + if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_SCO)) { + return device; + } + } + } + return NULL; +} + +/* Open/Close BT SCO if it is possible */ +static int update_bt_sco_state(pa_device_manager *dm, bool open) { + dm_device_bt_sco_status_t sco_status; + pa_tz_device *bt_device; + + pa_assert(dm); + + bt_device = _get_sco_connected_device(dm); + if (bt_device == NULL) { + pa_log_debug("No SCO connected bt device"); + return 0; + } else + pa_log_info("Got BT SCO connected device(%u)", bt_device->id); + + if (pa_tz_device_sco_get_status(bt_device, &sco_status) < 0) { + pa_log_error("get BT SCO status failed"); + return -1; + } + + if (sco_status == DM_DEVICE_BT_SCO_STATUS_DISCONNECTED) { + pa_log_info("BT SCO is not available for this BT device"); + return 0; + } + if (open) { + if (sco_status == DM_DEVICE_BT_SCO_STATUS_CONNECTED) { + if (pa_tz_device_sco_open(bt_device) < 0) { + pa_log_error("failed to open BT SCO"); + return -1; + } else + pa_log_debug("BT SCO is now opened"); + } else + pa_log_error("BT SCO is already opened for this BT device"); + } else { + if (sco_status == DM_DEVICE_BT_SCO_STATUS_OPENED) { + if (pa_tz_device_sco_close(bt_device) < 0) { + pa_log_error("BT SCO was opened, but failed to close SCO"); + return -1; + } else + pa_log_debug("BT SCO is now closed"); + } else + pa_log_error("BT SCO is already closed for this BT device"); + } + + return 0; +} + +/* Load/Unload module-loopback */ +static void update_loopback_module(struct userdata *u, bool load) { + char *args = NULL; + + pa_assert(u); + + if (load && u->loopback_args.sink && u->loopback_args.source) { + if (!u->loopback_args.latency_msec || !u->loopback_args.latency_msec) { + u->loopback_args.latency_msec = LOOPBACK_DEFAULT_LATENCY_MSEC; + u->loopback_args.adjust_sec = LOOPBACK_DEFAULT_ADJUST_SEC; + } + args = pa_sprintf_malloc("sink=%s source=%s latency_msec=%d adjust_time=%d", + u->loopback_args.sink->name, u->loopback_args.source->name, + u->loopback_args.latency_msec, u->loopback_args.adjust_sec); + if (u->module_loopback) + pa_module_unload(u->core, u->module_loopback, true); + + u->module_loopback = pa_module_load(u->core, MODULE_LOOPBACK, args); + + pa_log_info(" -- load module-loopback with (%s)", args); + pa_xfree(args); + + } else if (!load) { + if (u->module_loopback) { + pa_module_unload(u->core, u->module_loopback, true); + u->module_loopback = NULL; + u->loopback_args.sink = NULL; + u->loopback_args.source = NULL; + pa_log_info(" -- unload module-loopback"); + } + } else { + pa_log_error(" -- failed to update loopback module"); + } +} + /* Set the proper sink(source) according to the data of the parameter. * - ROUTE_TYPE_AUTO(_ALL) * 1. Find the proper sink/source comparing between avail_devices @@ -441,124 +556,6 @@ static pa_hook_result_t select_proper_sink_or_source_hook_cb(pa_core *c, pa_stre return PA_HOOK_OK; } -/* The state of a device using internal audio codec is handled here. - * Regarding the state of an external device, those is handled in device-manager.c */ -static void set_device_state_if_using_internal_codec(pa_tz_device *device, stream_type_t stream_type, dm_device_state_t device_state) { - bool use_internal_codec = false; - dm_device_direction_t direction; - - pa_assert(device); - - direction = pa_tz_device_get_direction(device); - if (IS_AVAILABLE_DIRECTION(stream_type, direction)) - if ((use_internal_codec = pa_tz_device_is_use_internal_codec(device))) - pa_tz_device_set_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state); - - return; -} - -/* threre is only one sco connected device */ -static pa_tz_device* _get_sco_connected_device(pa_device_manager *dm) { - pa_idxset *device_list; - pa_tz_device *device; - uint32_t device_idx; - - pa_assert(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)) { - /* FIXME : not works */ - if (pa_tz_device_have_profile(device, DEVICE_PROFILE_BT_SCO)) { - return device; - } - } - } - return NULL; -} - -/* Open/Close BT SCO if it is possible */ -static int update_bt_sco_state(pa_device_manager *dm, bool open) { - dm_device_bt_sco_status_t sco_status; - pa_tz_device *bt_device; - - pa_assert(dm); - - bt_device = _get_sco_connected_device(dm); - if (bt_device == NULL) { - pa_log_debug("No SCO connected bt device"); - return 0; - } else - pa_log_info("Got BT SCO connected device(%u)", bt_device->id); - - if (pa_tz_device_sco_get_status(bt_device, &sco_status) < 0) { - pa_log_error("get BT SCO status failed"); - return -1; - } - - if (sco_status == DM_DEVICE_BT_SCO_STATUS_DISCONNECTED) { - pa_log_info("BT SCO is not available for this BT device"); - return 0; - } - if (open) { - if (sco_status == DM_DEVICE_BT_SCO_STATUS_CONNECTED) { - if (pa_tz_device_sco_open(bt_device) < 0) { - pa_log_error("failed to open BT SCO"); - return -1; - } else - pa_log_debug("BT SCO is now opened"); - } else - pa_log_error("BT SCO is already opened for this BT device"); - } else { - if (sco_status == DM_DEVICE_BT_SCO_STATUS_OPENED) { - if (pa_tz_device_sco_close(bt_device) < 0) { - pa_log_error("BT SCO was opened, but failed to close SCO"); - return -1; - } else - pa_log_debug("BT SCO is now closed"); - } else - pa_log_error("BT SCO is already closed for this BT device"); - } - - return 0; -} - -/* Load/Unload module-loopback */ -static void update_loopback_module(struct userdata *u, bool load) { - char *args = NULL; - - pa_assert(u); - - if (load && u->loopback_args.sink && u->loopback_args.source) { - if (!u->loopback_args.latency_msec || !u->loopback_args.latency_msec) { - u->loopback_args.latency_msec = LOOPBACK_DEFAULT_LATENCY_MSEC; - u->loopback_args.adjust_sec = LOOPBACK_DEFAULT_ADJUST_SEC; - } - args = pa_sprintf_malloc("sink=%s source=%s latency_msec=%d adjust_time=%d", - u->loopback_args.sink->name, u->loopback_args.source->name, - u->loopback_args.latency_msec, u->loopback_args.adjust_sec); - if (u->module_loopback) - pa_module_unload(u->core, u->module_loopback, true); - - u->module_loopback = pa_module_load(u->core, MODULE_LOOPBACK, args); - - pa_log_info(" -- load module-loopback with (%s)", args); - pa_xfree(args); - - } else if (!load) { - if (u->module_loopback) { - pa_module_unload(u->core, u->module_loopback, true); - u->module_loopback = NULL; - u->loopback_args.sink = NULL; - u->loopback_args.source = NULL; - pa_log_info(" -- unload module-loopback"); - } - } else { - pa_log_error(" -- failed to update loopback module"); - } -} - /* Change the route setting according to the data from argument. * This function is called only when it needs to change routing path via HAL. * - stream is null @@ -706,6 +703,9 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_log_debug(" ** found a matched device: type[%-16s], direction[0x%x]", dm_device_type, dm_device_direction); use_internal_codec = pa_tz_device_is_use_internal_codec(device); if (use_internal_codec) { + /* if the device type is forwarding, keep going to next device for proper UCM setting */ + if (pa_streq(dm_device_type, DEVICE_TYPE_FORWARDING)) + continue; hal_direction = CONVERT_TO_HAL_DIRECTION(data->stream_type); route_info.num_of_devices++; route_info.device_infos = pa_xrealloc(route_info.device_infos, sizeof(hal_device_info)*route_info.num_of_devices); @@ -1112,8 +1112,6 @@ static void update_connected_devices(const char *device_type, dm_device_directio *ptr_in = 0; if (*ptr_out < 0) *ptr_out = 0; - - return; } static void dump_connected_devices() @@ -1126,7 +1124,6 @@ static void dump_connected_devices() pa_log_debug("in: %d, out: %d", cached_connected_devices[i][CACHED_DEVICE_DIRECTION_IN], cached_connected_devices[i][CACHED_DEVICE_DIRECTION_OUT]); pa_log_debug("================================"); #endif - return; } /* Reorganize routing when a device has been connected or disconnected */ @@ -1356,6 +1353,5 @@ void pa__done(pa_module *m) pa_xfree(u); - pa_log_info("Tizen Audio Policy module is unloaded\n"); } diff --git a/src/stream-manager-priv.h b/src/stream-manager-priv.h index e595d77..343d9e5 100644 --- a/src/stream-manager-priv.h +++ b/src/stream-manager-priv.h @@ -111,6 +111,7 @@ struct _stream_manager { pa_hashmap *latency_infos; pa_hashmap *stream_parents; pa_hashmap *muted_streams; + pa_idxset *mirroring_streams; cur_max_priority_stream cur_highest_priority; stream_restrictions restrictions; diff --git a/src/stream-manager-volume.c b/src/stream-manager-volume.c index 3c0c062..051a287 100644 --- a/src/stream-manager-volume.c +++ b/src/stream-manager-volume.c @@ -701,8 +701,6 @@ static void dump_volumes(pa_stream_manager *m) { while (m->volume_modifiers && (gain_value = pa_hashmap_iterate(m->volume_modifiers, &state, (const void**)&modifier_gain))) pa_log_debug("[modifier gain:%s, value:%f]", modifier_gain, *gain_value); pa_log_debug("===========[END volume infos dump]==========="); - - return; } int32_t init_volumes(pa_stream_manager *m) { @@ -774,8 +772,6 @@ void deinit_volumes(pa_stream_manager *m) { pa_xfree(gain); pa_hashmap_free(m->volume_modifiers); } - - return; } int32_t pa_stream_manager_volume_get_max_level(pa_stream_manager *m, stream_type_t stream_type, const char *volume_type, uint32_t *volume_level) { diff --git a/src/stream-manager.c b/src/stream-manager.c index 13b80eb..d2f7918 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -769,7 +769,6 @@ fail: pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID)); pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_set_stream_route_option(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -835,7 +834,6 @@ static void handle_set_stream_route_option(DBusConnection *conn, DBusMessage *ms pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_set_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -881,8 +879,6 @@ finish: if (!ret) send_volume_changed_signal(conn, direction, type, level); - - return; } static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -926,7 +922,6 @@ static void handle_get_volume_level(DBusConnection *conn, DBusMessage *msg, void finish: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -969,7 +964,6 @@ static void handle_get_volume_max_level(DBusConnection *conn, DBusMessage *msg, finish: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -1010,7 +1004,6 @@ static void handle_set_volume_mute(DBusConnection *conn, DBusMessage *msg, void finish: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -1054,7 +1047,6 @@ static void handle_get_volume_mute(DBusConnection *conn, DBusMessage *msg, void fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -1109,7 +1101,6 @@ static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *ms fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -1169,7 +1160,6 @@ static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, v fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -1199,7 +1189,6 @@ static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, vo fail: pa_assert_se(dbus_connection_send(conn, reply, NULL)); dbus_message_unref(reply); - return; } static DBusHandlerResult handle_methods(DBusConnection *conn, DBusMessage *msg, void *userdata) { @@ -1366,7 +1355,6 @@ static void dump_stream_map(pa_stream_manager *m) { pa_log_debug(" name[%d] : %s", idx, name); } pa_log_debug("===========[END stream-map dump]==========="); - return; } static int init_stream_map(pa_stream_manager *m) { @@ -1646,8 +1634,6 @@ static void deinit_stream_map(pa_stream_manager *m) { } pa_hashmap_free(m->latency_infos); } - - return; } static bool check_name_to_skip(pa_stream_manager *m, process_command_type_t command, void *stream, stream_type_t type, bool is_new_data) { @@ -1682,7 +1668,7 @@ static bool check_name_to_skip(pa_stream_manager *m, process_command_type_t comm return ret; } -static bool check_role_to_skip(pa_stream_manager *m, const char *role) { +static bool check_role_to_skip(pa_stream_manager *m, process_command_type_t command, const char *role) { bool ret = true; stream_info *s = NULL; @@ -1691,7 +1677,11 @@ static bool check_role_to_skip(pa_stream_manager *m, const char *role) { pa_assert(role); if ((s = pa_hashmap_get(m->stream_infos, role))) - ret = false; + ret = false; + if (s && pa_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING) && + (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED || + command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED)) + ret = true; pa_log_debug("role is [%s], skip(%d)", role, ret); @@ -2138,8 +2128,6 @@ static void update_buffer_attribute(pa_stream_manager *m, void *new_data, stream pa_log_info("*** maxlength:%d, fragsize:%d", maxlength, fragsize); } - - return; } static void fill_device_info_to_hook_data(pa_stream_manager *m, void *hook_data, notify_command_type_t command, stream_type_t type, void *stream, bool is_new_data) { @@ -2232,7 +2220,6 @@ static void fill_device_info_to_hook_data(pa_stream_manager *m, void *hook_data, default: break; } - return; } static void do_notify(pa_stream_manager *m, notify_command_type_t command, stream_type_t type, bool is_new_data, void *user_data) { @@ -2377,7 +2364,47 @@ static void do_notify(pa_stream_manager *m, notify_command_type_t command, strea break; } } - return; +} + +static void update_mirroring_streams(pa_stream_manager *m, pa_source_output *o, bool put) { + const char *role; + + pa_assert(m); + 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)) { + if (put) + pa_idxset_put(m->mirroring_streams, o, NULL); + else + pa_idxset_remove_by_data(m->mirroring_streams, o, NULL); + } +} + +/* Load/unload forwarding device */ +static int update_forwarding_device(pa_stream_manager *m, bool load) { + pa_assert(m); + + if (load) { + if (pa_idxset_size(m->mirroring_streams) == 0) { + if (!pa_device_manager_load_forwarding(m->dm)) { + pa_log_error("could not load forwarding device"); + return -1; + } else + pa_log_info("forwarding device is now loaded"); + } else + pa_log_debug("forwarding device has been already loaded"); + + } else { + if (pa_idxset_size(m->mirroring_streams) > 0) + pa_log_debug("no need to unload forwarding device"); + else { + pa_device_manager_unload_forwarding(m->dm); + pa_log_info("forwarding device is now unloaded"); + } + } + + return 0; } static process_stream_result_t process_stream(pa_stream_manager *m, void *stream, stream_type_t type, process_command_type_t command, bool is_new_data) { @@ -2447,10 +2474,13 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream pa_log_warn("role is null, set default to [%s]", role); } else { /* skip roles */ - if (check_role_to_skip(m, role)) { + if (check_role_to_skip(m, command, role)) { result = PROCESS_STREAM_RESULT_SKIP; goto finish; } + /* load forwarding device */ + if (type == STREAM_SOURCE_OUTPUT && pa_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) + update_forwarding_device(m, true); } /* update the priority of this stream */ ret = update_priority_of_stream(m, stream, type, role, is_new_data); @@ -2501,7 +2531,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream } /* skip roles */ - if (check_role_to_skip(m, role)) { + if (check_role_to_skip(m, command, role)) { result = PROCESS_STREAM_RESULT_SKIP; goto finish; } @@ -2562,8 +2592,12 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream } else if (command == PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED) { role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); if (role) { + /* unload forwarding device */ + if (type == STREAM_SOURCE_OUTPUT && pa_streq(role, STREAM_ROLE_LOOPBACK_MIRRORING)) + update_forwarding_device(m, false); + /* skip roles */ - if (check_role_to_skip(m, role)) { + if (check_role_to_skip(m, command, role)) { result = PROCESS_STREAM_RESULT_SKIP; goto finish; } @@ -2606,7 +2640,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); if (role) { /* skip roles */ - if (check_role_to_skip(m, role)) { + if (check_role_to_skip(m, command, role)) { result = PROCESS_STREAM_RESULT_SKIP; goto finish; } @@ -2654,7 +2688,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream role = pa_proplist_gets(GET_STREAM_PROPLIST(stream, type), PA_PROP_MEDIA_ROLE); if (role) { /* skip roles */ - if (check_role_to_skip(m, role)) { + if (check_role_to_skip(m, command, role)) { result = PROCESS_STREAM_RESULT_SKIP; goto finish; } @@ -2712,8 +2746,6 @@ static void remove_sink_input_from_muted_streams(pa_stream_manager *m, pa_sink_i PA_IDXSET_FOREACH(si, streams, idx) if (si == i) pa_idxset_remove_by_data(streams, i, NULL); - - return; } static pa_hook_result_t sink_input_new_cb(pa_core *core, pa_sink_input_new_data *new_data, pa_stream_manager *m) { @@ -2830,6 +2862,7 @@ static pa_hook_result_t source_output_put_cb(pa_core *core, pa_source_output *o, pa_log_info("start source_output_put_cb, o(%p, index:%u)", o, o->index); + update_mirroring_streams(m, o, true); process_stream(m, o, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_ADD_PARENT_ID, false); return PA_HOOK_OK; @@ -2841,6 +2874,7 @@ static pa_hook_result_t source_output_unlink_cb(pa_core *core, pa_source_output pa_log_info("start source_output_unlink_cb, o(%p, index:%u)", o, o->index); + update_mirroring_streams(m, o, false); process_stream(m, o, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_ENDED, false); process_stream(m, o, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_REMOVE_PARENT_ID, false); @@ -2964,8 +2998,6 @@ static void find_next_device_for_auto_route(pa_stream_manager *m, stream_route_t } pa_log_debug("next_device is [%p] for role[%s]/route_type[%d]/stream_type[%d]", *next_device, role, route_type, stream_type); - - return; } static void is_available_device_for_auto_route(pa_stream_manager *m, stream_route_type_t route_type, const char *cur_device_type, const char *new_device_type, const char *role, stream_type_t stream_type, bool *available) { @@ -3012,8 +3044,6 @@ static void is_available_device_for_auto_route(pa_stream_manager *m, stream_rout } pa_log_debug("is new_device[%s] available for role[%s]/stream_type[%d]:%d", new_device_type, role, stream_type, *available); - - return; } /* Re-trigger for routing update for streams using auto route type */ @@ -3045,8 +3075,6 @@ static void process_stream_as_device_change_for_auto_route(pa_stream_manager *m, if (use_internal_codec) process_stream(m, stream, stream_type, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_STARTED, false); } - - return; } /* The state of a device using internal audio codec is handled here. @@ -3058,8 +3086,6 @@ static void set_device_state_if_using_internal_codec(pa_tz_device *device, strea if ((use_internal_codec = pa_tz_device_is_use_internal_codec(device))) pa_tz_device_set_state(device, CONVERT_TO_DEVICE_DIRECTION(stream_type), device_state); - - return; } static void update_sink_or_source_as_device_change(stream_route_type_t stream_route_type, pa_idxset *streams, @@ -3251,8 +3277,6 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro } } else pa_log_error("[SM][UPDATE_SINK_SOURCE] could not handle it here, stream_route_type(%d)", stream_route_type); - - return; } static void mute_sink_inputs_as_device_disconnection(pa_stream_manager *m, uint32_t event_id, bool need_to_mute, void *user_data) { @@ -3286,6 +3310,7 @@ static void mute_sink_inputs_as_device_disconnection(pa_stream_manager *m, uint3 PA_IDXSET_FOREACH(i, muted_streams, s_idx) { pa_idxset_remove_by_data(muted_streams, i, NULL); pa_sink_input_remove_volume_factor(i, mute_key); + pa_log_debug("found a stream(%p, %u) that should be un-muted.", i, i->index); } pa_hashmap_remove(m->muted_streams, (void*)event_id); pa_idxset_free(muted_streams, NULL); @@ -3502,8 +3527,6 @@ static void message_cb(const char *name, int value, void *user_data) { send_command_signal(pa_dbus_connection_get(m->dbus_conn), name, value); } #endif - - return; } static int32_t init_ipc(pa_stream_manager *m) { @@ -3567,7 +3590,6 @@ static void deinit_ipc(pa_stream_manager *m) { } #endif #endif - return; } bool pa_stream_manager_check_name_is_vstream(void *stream, stream_type_t type, bool is_new_data) { @@ -3606,6 +3628,7 @@ pa_stream_manager* pa_stream_manager_init(pa_core *c) { goto fail; m->stream_parents = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); m->muted_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); + m->mirroring_streams = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); m->sink_input_new_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_new_cb, m); m->sink_input_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_PUT], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_put_cb, m); @@ -3691,6 +3714,12 @@ void pa_stream_manager_done(pa_stream_manager *m) { pa_hashmap_free(m->muted_streams); } + if (m->mirroring_streams) { + if (pa_idxset_size(m->mirroring_streams)) + update_forwarding_device(m, false); + pa_idxset_free(m->mirroring_streams, NULL); + } + if (m->stream_parents) pa_hashmap_free(m->stream_parents); diff --git a/src/stream-manager.h b/src/stream-manager.h index 2e50746..0fb6f23 100644 --- a/src/stream-manager.h +++ b/src/stream-manager.h @@ -36,15 +36,16 @@ #define GET_STREAM_PROPLIST(stream, type) \ (type == STREAM_SINK_INPUT ? ((pa_sink_input*)stream)->proplist : ((pa_source_output*)stream)->proplist) -#define STREAM_ROLE_CALL_VOICE "call-voice" -#define STREAM_ROLE_CALL_VIDEO "call-video" -#define STREAM_ROLE_VOIP "voip" -#define STREAM_ROLE_LOOPBACK "loopback" -#define STREAM_ROLE_RADIO "radio" - -#define SINK_NAME_COMBINED "sink_combined" -#define SINK_NAME_NULL "sink_null" -#define SOURCE_NAME_NULL "source_null" +#define STREAM_ROLE_CALL_VOICE "call-voice" +#define STREAM_ROLE_CALL_VIDEO "call-video" +#define STREAM_ROLE_VOIP "voip" +#define STREAM_ROLE_LOOPBACK "loopback" +#define STREAM_ROLE_LOOPBACK_MIRRORING "loopback-mirroring" +#define STREAM_ROLE_RADIO "radio" + +#define SINK_NAME_COMBINED "sink_combined" +#define SINK_NAME_NULL "sink_null" +#define SOURCE_NAME_NULL "source_null" typedef struct _stream_manager pa_stream_manager; -- 2.7.4 From 51278fab7836e01c59a87063405a83a821c040f4 Mon Sep 17 00:00:00 2001 From: Hyunseok Lee Date: Tue, 27 Sep 2016 14:20:16 +0900 Subject: [PATCH 05/16] Remove dlog dependency & fix indent [Version] 5.0.82 [Profile] Common [Issue Type] CleanUp Change-Id: I40a6018caf470ae5019edb1ef1f98e9fc1b5f771 --- configure.ac | 18 ------------------ packaging/pulseaudio-modules-tizen.spec | 8 +------- src/module-tizenaudio-policy.c | 2 +- 3 files changed, 2 insertions(+), 26 deletions(-) diff --git a/configure.ac b/configure.ac index 98222a9..34b05f8 100644 --- a/configure.ac +++ b/configure.ac @@ -360,24 +360,6 @@ PKG_CHECK_MODULES(VCONF, vconf) AC_SUBST(VCONF_CFLAGS) AC_SUBST(VCONF_LIBS) -dnl use dlog -------------------------------------------------------------------------- -AC_ARG_ENABLE(dlog, AC_HELP_STRING([--enable-dlog], [using dlog]), -[ - case "${enableval}" in - yes) USE_DLOG=yes ;; - no) USE_DLOG=no ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-dlog) ;; - esac - ],[USE_DLOG=no]) - -if test "x$USE_DLOG" = "xyes"; then -PKG_CHECK_MODULES(DLOG, dlog) -AC_SUBST(DLOG_CFLAGS) -AC_SUBST(DLOG_LIBS) -fi -AM_CONDITIONAL(USE_DLOG, test "x$USE_DLOG" = "xyes") -dnl end -------------------------------------------------------------------- - dnl use hal tc ------------------------------------------------------------ AC_ARG_ENABLE(haltc, AC_HELP_STRING([--enable-haltc], [using haltc]), [ diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 3a6a20f..1105206 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: 5.0.81 +Version: 5.0.82 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ @@ -19,9 +19,6 @@ BuildRequires: pkgconfig(pulsecore) BuildRequires: pkgconfig(libsystemd) BuildRequires: pulseaudio BuildRequires: m4 -%if %{with pulseaudio_dlog} -BuildRequires: pkgconfig(dlog) -%endif Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig @@ -37,9 +34,6 @@ export CFLAGS="%{optflags} -fno-strict-aliasing -DSYSCONFDIR=\\\"%{_sysconfdir}\ export LD_AS_NEEDED=0 %reconfigure --prefix=%{_prefix} \ --disable-static \ -%if %{with pulseaudio_dlog} - --enable-dlog \ -%endif # --enable-haltc %__make %{?_smp_mflags} V=1 diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index b3976e6..8cfeca9 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -1020,7 +1020,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ /* make sure the previous device is closed */ if (data->stream_type == STREAM_SINK_INPUT) pa_sink_suspend(sink, true, PA_SUSPEND_INTERNAL); - else if(data->stream_type == STREAM_SOURCE_OUTPUT) + else if (data->stream_type == STREAM_SOURCE_OUTPUT) pa_source_suspend(source, true, PA_SUSPEND_INTERNAL); } -- 2.7.4 From 84e799edfe81f530a284271b839474e0244ab8f0 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 4 Oct 2016 16:53:33 +0900 Subject: [PATCH 06/16] stream-manager: Modify handle_update_focus_status() to update only if needed Previously, all the playback/recording streams are updated even if only one focus type(playback/capture) is changed. It is fixed to update only if needed by checking change of each focus type. [Version] 5.0.83 [Profile] Common [Issue Type] Feature enhancement Change-Id: Icfc6434d706a76ca51a7727f5585f7bd6127ce77 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager-priv.h | 2 +- src/stream-manager.c | 25 +++++++++++++------------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 1105206..d662d86 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: 5.0.82 +Version: 5.0.83 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager-priv.h b/src/stream-manager-priv.h index 343d9e5..ec71b6e 100644 --- a/src/stream-manager-priv.h +++ b/src/stream-manager-priv.h @@ -57,7 +57,7 @@ typedef enum _stream_direction { #define GET_STREAM_SAMPLE_SPEC(stream, type) \ (type == STREAM_SINK_INPUT ? ((pa_sink_input*)stream)->sample_spec : ((pa_source_output*)stream)->sample_spec) -#define IS_FOCUS_ACQUIRED(focus, type) \ +#define GET_FOCUS_STATUS(focus, type) \ (type == STREAM_SINK_INPUT ? (focus & STREAM_FOCUS_ACQUIRED_PLAYBACK) : (focus & STREAM_FOCUS_ACQUIRED_CAPTURE)) typedef struct _volume_info { diff --git a/src/stream-manager.c b/src/stream-manager.c index d2f7918..8652fbf 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -1112,6 +1112,7 @@ static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, v void *stream = NULL; DBusMessage *reply = NULL; pa_stream_manager *m = (pa_stream_manager*)userdata; + int prev_status = STREAM_FOCUS_ACQUIRED_NONE; pa_assert(conn); pa_assert(msg); @@ -1125,25 +1126,25 @@ static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, v pa_assert_se((reply = dbus_message_new_method_return(msg))); - sp = pa_hashmap_get(m->stream_parents, (const void*)id); - if (sp) { - if (sp->focus_status != (acquired_focus_status & (STREAM_FOCUS_ACQUIRED_PLAYBACK|STREAM_FOCUS_ACQUIRED_CAPTURE))) { + if ((sp = pa_hashmap_get(m->stream_parents, (const void*)id))) { + if (sp->focus_status != acquired_focus_status) { /* need to update */ - sp->focus_status = acquired_focus_status & (STREAM_FOCUS_ACQUIRED_PLAYBACK|STREAM_FOCUS_ACQUIRED_CAPTURE); - if (sp->idx_sink_inputs) { + prev_status = sp->focus_status; + sp->focus_status = acquired_focus_status; + if (((prev_status ^ sp->focus_status) & STREAM_FOCUS_ACQUIRED_PLAYBACK) && sp->idx_sink_inputs) { count = pa_idxset_size(sp->idx_sink_inputs); PA_IDXSET_FOREACH(stream, sp->idx_sink_inputs, idx) { pa_proplist_sets(GET_STREAM_PROPLIST(stream, STREAM_SINK_INPUT), PA_PROP_MEDIA_FOCUS_STATUS, - IS_FOCUS_ACQUIRED(sp->focus_status, STREAM_SINK_INPUT) ? STREAM_FOCUS_PLAYBACK : STREAM_FOCUS_NONE); + GET_FOCUS_STATUS(sp->focus_status, STREAM_SINK_INPUT) ? STREAM_FOCUS_PLAYBACK : STREAM_FOCUS_NONE); if (--count == 0) process_stream(m, stream, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED, false); } } - if (sp->idx_source_outputs) { + if (((prev_status ^ sp->focus_status) & STREAM_FOCUS_ACQUIRED_CAPTURE) && sp->idx_source_outputs) { count = pa_idxset_size(sp->idx_source_outputs); PA_IDXSET_FOREACH(stream, sp->idx_source_outputs, idx) { pa_proplist_sets(GET_STREAM_PROPLIST(stream, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_FOCUS_STATUS, - IS_FOCUS_ACQUIRED(sp->focus_status, STREAM_SOURCE_OUTPUT) ? STREAM_FOCUS_CAPTURE : STREAM_FOCUS_NONE); + GET_FOCUS_STATUS(sp->focus_status, STREAM_SOURCE_OUTPUT) ? STREAM_FOCUS_CAPTURE : STREAM_FOCUS_NONE); if (--count == 0) process_stream(m, stream, STREAM_SOURCE_OUTPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED, false); } @@ -1942,8 +1943,8 @@ static bool update_the_highest_priority_stream(pa_stream_manager *m, process_com return false; } else { if (priority && cur_max_priority) { - if (IS_FOCUS_ACQUIRED(focus_status, type) || - (!IS_FOCUS_ACQUIRED(cur_max_focus_status, type) && *priority >= *cur_max_priority)) { + if (GET_FOCUS_STATUS(focus_status, type) || + (!GET_FOCUS_STATUS(cur_max_focus_status, type) && *priority >= *cur_max_priority)) { *need_to_update = true; pa_log_debug("update cur_highest to mine(%s)", role); } else { @@ -2009,8 +2010,8 @@ static bool update_the_highest_priority_stream(pa_stream_manager *m, process_com cur_max_role = _role; } if (cur_max_priority && priority) { - if (IS_FOCUS_ACQUIRED(cur_max_focus_status, type) || - (!IS_FOCUS_ACQUIRED(focus_status, type) && (*cur_max_priority > *priority))) { + if (GET_FOCUS_STATUS(cur_max_focus_status, type) || + (!GET_FOCUS_STATUS(focus_status, type) && (*cur_max_priority > *priority))) { /* skip */ } else { cur_max_priority = priority; -- 2.7.4 From 706adaad05d9baca33e5f4d2f022cec5c38e1421 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Fri, 7 Oct 2016 15:30:55 +0900 Subject: [PATCH 07/16] stream-manager: Add device_profile_changed_hook_cb to update proper sink in case of active profile of BT device change It is related to the previous commit regarding device-manage: avail-mode for bt. The previous logic about device connected callback for BT was changed from that commit, so some issues happened. Now, this commit supports the device-manager changes and works well with the scenario of BT profile change. [Version] 5.0.84 [Profile] Common [Issue Type] Fix bug Change-Id: I6623fc94f33f4ec296961f0216ad13760e1f4f0c Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-policy.c | 4 +++- src/stream-manager-priv.h | 1 + src/stream-manager.c | 41 +++++++++++++++++++++++++++++++-- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index d662d86..a06cef8 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: 5.0.83 +Version: 5.0.84 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index 8cfeca9..ce6ea54 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -706,6 +706,8 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ /* if the device type is forwarding, keep going to next device for proper UCM setting */ if (pa_streq(dm_device_type, DEVICE_TYPE_FORWARDING)) continue; + if (pa_streq(dm_device_type, DEVICE_TYPE_BT)) + continue; hal_direction = CONVERT_TO_HAL_DIRECTION(data->stream_type); route_info.num_of_devices++; route_info.device_infos = pa_xrealloc(route_info.device_infos, sizeof(hal_device_info)*route_info.num_of_devices); @@ -1219,7 +1221,7 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi return PA_HOOK_OK; } -/* Update connected device list when a device's information has been changed */ +/* Update connected device list when a device profile has been changed */ static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_profile_changed *conn, struct userdata *u) { dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT; int* ptr_in = NULL; diff --git a/src/stream-manager-priv.h b/src/stream-manager-priv.h index ec71b6e..c47152e 100644 --- a/src/stream-manager-priv.h +++ b/src/stream-manager-priv.h @@ -141,6 +141,7 @@ struct _stream_manager { struct { pa_communicator *comm; pa_hook_slot *comm_hook_device_connection_changed_slot; + pa_hook_slot *comm_hook_device_profile_changed_slot; pa_hook_slot *comm_hook_event_fully_handled_slot; } comm; }; diff --git a/src/stream-manager.c b/src/stream-manager.c index 8652fbf..30e3238 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3179,7 +3179,7 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro } } else if (!is_connected) { /* DISCONNECTED: find a connected device that has the next priority */ - if (sink && (sink == ((pa_sink_input*)s)->sink)) { + if (sink) { find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); if (next_device) { if ((next_sink = pa_tz_device_get_sink(next_device, DEVICE_ROLE_NORMAL))) { @@ -3204,7 +3204,7 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro s, ((pa_sink_input*)s)->index, null_sink, null_sink->name); } - } else if (source && (source == ((pa_source_output*)s)->source)) { + } else if (source) { find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); if (next_device) { if ((next_source = pa_tz_device_get_source(next_device, DEVICE_ROLE_NORMAL))) { @@ -3450,6 +3450,41 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi return PA_HOOK_OK; } +/* Update connected device list when a device profile has been changed */ +static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_profile_changed *conn, pa_stream_manager *m) { + dm_device_direction_t device_direction = DM_DEVICE_DIRECTION_OUT; + bool use_internal_codec = false; + bool bt_sink_available = false; + + pa_assert(c); + pa_assert(conn); + pa_assert(m); + + device_direction = pa_tz_device_get_direction(conn->device); + use_internal_codec = pa_tz_device_is_use_internal_codec(conn->device); + + pa_log_info("[SM][CONN] device_profile_changed_hook_cb is called. conn(%p), changed(%d), device(%p), direction(0x%x), use_internal_codec(%d)", + conn, conn->changed, conn->device, device_direction, use_internal_codec); + + if (conn->changed == PA_TZ_DEVICE_ACTIVE_PROFILE_CHANGED) { + if (pa_streq(pa_tz_device_get_type(conn->device), DEVICE_TYPE_BT)) { + pa_log_info("[SM][CONN] BT: active profile changed to [%s]", pa_tz_device_get_profile(conn->device)); + if (use_internal_codec) + bt_sink_available = false; /* already bt device is connected and A2DP is newly deactivated, now SCO is only activated */ + else + bt_sink_available = true; /* already bt device is connected and A2DP is newly activated */ + } + if (device_direction & DM_DEVICE_DIRECTION_OUT) { + update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_AUTO, m->core->sink_inputs, + STREAM_SINK_INPUT, conn->device, bt_sink_available, m); + update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED, m->core->sink_inputs, + STREAM_SINK_INPUT, conn->device, bt_sink_available, m); + } + } + + return PA_HOOK_OK; +} + static void subscribe_cb(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, pa_stream_manager *m) { pa_client *client = NULL; stream_parent *sp = NULL; @@ -3649,6 +3684,8 @@ pa_stream_manager* pa_stream_manager_init(pa_core *c) { m->comm.comm = pa_communicator_get(c); m->comm.comm_hook_device_connection_changed_slot = pa_hook_connect(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_DEVICE_CONNECTION_CHANGED), PA_HOOK_EARLY + 10, (pa_hook_cb_t)device_connection_changed_hook_cb, m); + m->comm.comm_hook_device_profile_changed_slot = pa_hook_connect(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_DEVICE_PROFILE_CHANGED), + PA_HOOK_EARLY + 10, (pa_hook_cb_t)device_profile_changed_hook_cb, m); m->comm.comm_hook_event_fully_handled_slot = pa_hook_connect(pa_communicator_hook(m->comm.comm, PA_COMMUNICATOR_HOOK_EVENT_FULLY_HANDLED), PA_HOOK_EARLY + 10, (pa_hook_cb_t)event_fully_handled_hook_cb, m); -- 2.7.4 From 4be4050cf73a1d1d67005122bb4c50d97c8c4b5d Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Mon, 10 Oct 2016 17:44:50 +0900 Subject: [PATCH 08/16] stream-manager: roll-back of the previous commit and add condition for selecting next device Although A2DP of BT device is off and it changes to SCO, the sink from the deivce should be same as BT sink(for A2DP). Because it does not work like that, new condition is added to avoid it temporarily. [Version] 5.0.85 [Profile] Common [Issue Type] Fix bug Change-Id: I23f30484d92890e9870ffbefadd0b6db5eb6c12a --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager.c | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index a06cef8..62a4d2d 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: 5.0.84 +Version: 5.0.85 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager.c b/src/stream-manager.c index 30e3238..eb48168 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3179,7 +3179,10 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro } } else if (!is_connected) { /* DISCONNECTED: find a connected device that has the next priority */ - if (sink) { + if (sink && (sink == ((pa_sink_input*)s)->sink) || + /* FIX ME: Although A2DP of BT device is off and it changes to SCO, sink from the device should be same as BT sink(for A2DP). + * Because it does not work like that, new condition is added to avoid it temporarily. */ + (pa_safe_streq(device_type, DEVICE_TYPE_BT) && pa_safe_streq(pa_tz_device_get_profile(device), "sco"))) { find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); if (next_device) { if ((next_sink = pa_tz_device_get_sink(next_device, DEVICE_ROLE_NORMAL))) { @@ -3200,11 +3203,11 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro if (!next_device || !next_sink) { pa_sink_input_move_to(s, null_sink, false); - pa_log_debug(" -- *** sink-input(%p,%u) moves to sink(%p,%s)", + pa_log_warn(" -- *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, null_sink, null_sink->name); } - } else if (source) { + } else if (source && (source == ((pa_source_output*)s)->source)) { find_next_device_for_auto_route(m, route_type, role, stream_type, device_type, &next_device); if (next_device) { if ((next_source = pa_tz_device_get_source(next_device, DEVICE_ROLE_NORMAL))) { @@ -3218,7 +3221,7 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro process_stream_as_device_change_for_auto_route(m, s, stream_type, is_connected, next_source->use_internal_codec); pa_source_output_move_to(s, next_source, false); - pa_log_debug(" -- *** source-output(%p,%u) moves to source(%p,%s), new device(%s)", + 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); } } -- 2.7.4 From 49053505d591e361aba30510e13a536ea1bf1442 Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Mon, 24 Oct 2016 16:15:41 +0900 Subject: [PATCH 09/16] stream-manager: Skip updating other streams in device_profile_changed_hook_cb() in case of the active profile is SCO The hook callback is called from module-tizenaudio-policy.c when calling SCO open function. In this case, it should not trigger routing update function for other streams which can lead to close SCO. [Version] 5.0.86 [Profile] Common [Issue Type] Fix bug Change-Id: I9c1a5e2a23d50c3e014be82eda6b8a553c9869e9 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-policy.c | 10 +++++----- src/stream-manager.c | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 62a4d2d..c409861 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: 5.0.85 +Version: 5.0.86 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index ce6ea54..29c22a1 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -995,14 +995,14 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL)) || !(dst_sink = pa_tz_device_get_sink(device, DEVICE_ROLE_CALL_VOICE)) || sink == dst_sink) - pa_log_debug("[ROUTE][CALL-VOICE] no need to move streams, sink(%p), dst_sink(%p)", sink, dst_sink); + pa_log_info("[ROUTE][CALL-VOICE] no need to move streams, sink(%p), dst_sink(%p)", sink, dst_sink); else streams = sink->inputs; } else if (data->stream_type == STREAM_SOURCE_OUTPUT) { if (!(source = pa_tz_device_get_source(device, DEVICE_ROLE_NORMAL)) || !(dst_source = pa_tz_device_get_source(device, DEVICE_ROLE_CALL_VOICE)) || source == dst_source) - pa_log_debug("[ROUTE][CALL-VOICE] no need to move streams, source(%p), dst_source(%p)", source, dst_source); + pa_log_info("[ROUTE][CALL-VOICE] no need to move streams, source(%p), dst_source(%p)", source, dst_source); else streams = source->outputs; } @@ -1011,11 +1011,11 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ PA_IDXSET_FOREACH(s, streams, idx) { if (data->stream_type == STREAM_SINK_INPUT) { pa_sink_input_move_to(s, dst_sink, false); - pa_log_debug("[ROUTE][CALL-VOICE] *** sink-input(%p,%u) moves to sink(%p,%s)", + pa_log_info("[ROUTE][CALL-VOICE] *** sink-input(%p,%u) moves to sink(%p,%s)", s, ((pa_sink_input*)s)->index, dst_sink, dst_sink->name); } else if (data->stream_type == STREAM_SOURCE_OUTPUT) { pa_source_output_move_to(s, dst_source, false); - pa_log_debug("[ROUTE][CALL-VOICE] *** source-output(%p,%u) moves to source(%p,%s)", + pa_log_info("[ROUTE][CALL-VOICE] *** source-output(%p,%u) moves to source(%p,%s)", s, ((pa_source_output*)s)->index, dst_source, dst_source->name); } } @@ -1031,7 +1031,7 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_stream_manager_check_name_is_vstream(data->stream, STREAM_SINK_INPUT, true)) { if ((sink = pa_tz_device_get_sink(device, data->device_role))) { *(data->proper_sink) = sink; - pa_log_debug("[ROUTE][RADIO] *** now, sink-input(%p,%u) uses the sink(%p,%s)", + pa_log_info("[ROUTE][RADIO] *** now, sink-input(%p,%u) uses the sink(%p,%s)", data->stream, ((pa_sink_input*)data->stream)->index, sink, sink->name); } } diff --git a/src/stream-manager.c b/src/stream-manager.c index eb48168..9b063b6 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3478,6 +3478,10 @@ static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_ bt_sink_available = true; /* already bt device is connected and A2DP is newly activated */ } if (device_direction & DM_DEVICE_DIRECTION_OUT) { + if (!bt_sink_available && pa_safe_streq(pa_tz_device_get_profile(conn->device), "sco")) { + pa_log_info("[SM][CONN] bt active profile is SCO, skip update others"); + return PA_HOOK_OK; + } update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_AUTO, m->core->sink_inputs, STREAM_SINK_INPUT, conn->device, bt_sink_available, m); update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED, m->core->sink_inputs, -- 2.7.4 From 140e95a061729a8b9c4bcc31bf717c3d10bc835c Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Tue, 25 Oct 2016 13:09:50 +0900 Subject: [PATCH 10/16] tizen-device: Change logic inside of _set_active_profile() Previously, the callback for notifying active profile changed is called even if the third argument of _set_active_profile() is false. In case of SCO open()/close() via device-manager API, the callback get triggered in stream-manager and should be considiered with additional logic. With this patch, the previous commit does not need anymore. Fix build warning of stream-manager.c. [Version] 5.0.87 [Profile] Common [Issue Type] Feature Enhancement Change-Id: I579fda5edbb0530b5439b7938c52d8d93ff1c565 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager.c | 6 +----- src/tizen-device.c | 10 ++++------ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index c409861..4f8c354 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: 5.0.86 +Version: 5.0.87 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager.c b/src/stream-manager.c index 9b063b6..37badeb 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -3179,7 +3179,7 @@ static void update_sink_or_source_as_device_change(stream_route_type_t stream_ro } } 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)) || /* FIX ME: Although A2DP of BT device is off and it changes to SCO, sink from the device should be same as BT sink(for A2DP). * Because it does not work like that, new condition is added to avoid it temporarily. */ (pa_safe_streq(device_type, DEVICE_TYPE_BT) && pa_safe_streq(pa_tz_device_get_profile(device), "sco"))) { @@ -3478,10 +3478,6 @@ static pa_hook_result_t device_profile_changed_hook_cb(pa_core *c, pa_tz_device_ bt_sink_available = true; /* already bt device is connected and A2DP is newly activated */ } if (device_direction & DM_DEVICE_DIRECTION_OUT) { - if (!bt_sink_available && pa_safe_streq(pa_tz_device_get_profile(conn->device), "sco")) { - pa_log_info("[SM][CONN] bt active profile is SCO, skip update others"); - return PA_HOOK_OK; - } update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_AUTO, m->core->sink_inputs, STREAM_SINK_INPUT, conn->device, bt_sink_available, m); update_sink_or_source_as_device_change(STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED, m->core->sink_inputs, diff --git a/src/tizen-device.c b/src/tizen-device.c index 2eabac8..26446a3 100644 --- a/src/tizen-device.c +++ b/src/tizen-device.c @@ -570,9 +570,8 @@ static pa_tz_profile* _get_active_profile(pa_tz_device *device) { return profile; } -/* if noti_always is true, always noti this change without checking index - * if profile is null, set first profile as active */ -int _set_active_profile(pa_tz_device *device, const char *profile, bool noti_always) { +/* if profile is null, set first profile as active */ +int _set_active_profile(pa_tz_device *device, const char *profile, bool noti) { uint32_t profile_idx, prev_active_idx; pa_assert(device); @@ -587,10 +586,9 @@ int _set_active_profile(pa_tz_device *device, const char *profile, bool noti_alw return -1; } device->active_profile = profile_idx; - pa_log_info("new active profile index %u", profile_idx); + pa_log_info("active profile index: prev(%u) -> new(%u)", prev_active_idx, profile_idx); - /* Compare index only when check_idx is true */ - if (noti_always || prev_active_idx != device->active_profile) + if (noti) notify_device_profile_changed(device, PA_TZ_DEVICE_ACTIVE_PROFILE_CHANGED); return 0; -- 2.7.4 From 406c0310be4b2f785da3c8e85862ca5570da2bef Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Wed, 26 Oct 2016 20:07:00 +0900 Subject: [PATCH 11/16] tizenaudio-policy: Refer to sound profile in case of ringtone-call playback If sound profile is off and ringtone-call stream is about to play, it blocks the stream not to go out to builtin-speaker. [Version] 5.0.88 [Profile] Common [Issue Type] Policy Change-Id: Ie93e3d5d875bba2bf66797c67a863e6621fda7a6 Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-policy.c | 30 ++++++++++++++++++++++++++---- src/stream-manager.h | 1 + 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 4f8c354..9c4f8de 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: 5.0.87 +Version: 5.0.88 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index 29c22a1..ab8c673 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -323,6 +323,30 @@ static void update_loopback_module(struct userdata *u, bool load) { } } +static bool skip_device(const char *stream_role, const char *device_type) +{ + int sound_on = 1; + + if (pa_streq(device_type, DEVICE_TYPE_FORWARDING)) + return true; + + if (pa_streq(device_type, DEVICE_TYPE_BT)) + return true; + + /* get sound profile */ + if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on) < 0) { + pa_log_error("failed to get vconf - sound status"); + return false; + } + + if (!sound_on && pa_streq(stream_role, STREAM_ROLE_RINGTONE_CALL) && pa_streq(device_type, DEVICE_TYPE_SPEAKER)) { + pa_log_info("sound status is 0 with ringtone-call stream, skip built-in speaker"); + return true; + } + + return false; +} + /* Set the proper sink(source) according to the data of the parameter. * - ROUTE_TYPE_AUTO(_ALL) * 1. Find the proper sink/source comparing between avail_devices @@ -703,10 +727,8 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ pa_log_debug(" ** found a matched device: type[%-16s], direction[0x%x]", dm_device_type, dm_device_direction); use_internal_codec = pa_tz_device_is_use_internal_codec(device); if (use_internal_codec) { - /* if the device type is forwarding, keep going to next device for proper UCM setting */ - if (pa_streq(dm_device_type, DEVICE_TYPE_FORWARDING)) - continue; - if (pa_streq(dm_device_type, DEVICE_TYPE_BT)) + /* if it needs to skip it, keep going to next device for proper UCM setting */ + if (skip_device(data->stream_role, dm_device_type)) continue; hal_direction = CONVERT_TO_HAL_DIRECTION(data->stream_type); route_info.num_of_devices++; diff --git a/src/stream-manager.h b/src/stream-manager.h index 0fb6f23..b90d65b 100644 --- a/src/stream-manager.h +++ b/src/stream-manager.h @@ -36,6 +36,7 @@ #define GET_STREAM_PROPLIST(stream, type) \ (type == STREAM_SINK_INPUT ? ((pa_sink_input*)stream)->proplist : ((pa_source_output*)stream)->proplist) +#define STREAM_ROLE_RINGTONE_CALL "ringtone-call" #define STREAM_ROLE_CALL_VOICE "call-voice" #define STREAM_ROLE_CALL_VIDEO "call-video" #define STREAM_ROLE_VOIP "voip" -- 2.7.4 From 8e503c115a406dee5e442d63655b4e82bd95cc62 Mon Sep 17 00:00:00 2001 From: KimJeongYeon Date: Wed, 19 Oct 2016 18:58:12 +0900 Subject: [PATCH 12/16] vconf: Implementation of module-vconf/vconf-helper Changes: * Based on module-gconf/gconf-helper. * Support hook callback to communicate with stream-manager/device-manager. * Included to TV product only. [Version] 5.0.89 [Profile] TV [Issue Type] Feature Enhancement Signed-off-by: KimJeongYeon Change-Id: I3c4946f9e774a8d6ce0016c134c7dfa356249966 (cherry picked from commit f79d6c1b1ef40519594eaa99a34e1241bf65d55c) --- Makefile.am | 33 +++- configure.ac | 16 ++ packaging/pulseaudio-modules-tizen.spec | 13 +- src/communicator.h | 1 + src/vconf/hook-data.h | 65 ++++++++ src/vconf/module-vconf.c | 274 ++++++++++++++++++++++++++++++++ src/vconf/vconf-helper.c | 112 +++++++++++++ 7 files changed, 511 insertions(+), 3 deletions(-) create mode 100644 src/vconf/hook-data.h create mode 100644 src/vconf/module-vconf.c create mode 100644 src/vconf/vconf-helper.c diff --git a/Makefile.am b/Makefile.am index 7421ffb..8f30b26 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,6 +18,7 @@ ACLOCAL_AMFLAGS = -I m4 pulsemodlibexecdir= $(libdir)/pulse-5.0/modules +pulselibexecdir=$(libexecdir)/pulse AM_CFLAGS = \ $(PTHREAD_CFLAGS) @@ -31,6 +32,7 @@ MODULE_LIBADD = $(AM_LIBADD) $(PACORE_LIBS) $(PA_LIBS) pulsemodlibexec_LTLIBRARIES = \ libhal-interface.la \ + libcommunicator.la \ module-tizenaudio-sink.la \ module-tizenaudio-source.la \ module-tizenaudio-policy.la \ @@ -44,6 +46,7 @@ endif # These are generated by an M4 script SYMDEF_FILES = \ libhal-interface-symdef.h \ + libcommunicator-symdef.h \ module-tizenaudio-sink-symdef.h \ module-tizenaudio-source-symdef.h \ module-tizenaudio-policy-symdef.h \ @@ -54,6 +57,11 @@ SYMDEF_FILES += \ module-tizenaudio-haltc-symdef.h endif +if ENABLE_VCONF_HELPER +SYMDEF_FILES += \ + module-vconf-symdef.h +endif + if HAVE_DBUS endif @@ -71,6 +79,12 @@ libhal_interface_la_LDFLAGS = $(AM_LDFLAGS) $(PA_LDFLAGS) -avoid-version libhal_interface_la_LIBADD = $(AM_LIBADD) $(PACORE_LIBS) $(PA_LIBS) libhal_interface_la_CFLAGS = $(AM_CFLAGS) $(PACORE_CFLAGS) $(PA_CFLAGS) +libcommunicator_la_SOURCES = \ + src/communicator.c src/communicator.h +libcommunicator_la_LDFLAGS = $(AM_LDFLAGS) $(PA_LDFLAGS) -avoid-version +libcommunicator_la_LIBADD = $(AM_LIBADD) $(PACORE_LIBS) $(PA_LIBS) +libcommunicator_la_CFLAGS = $(AM_CFLAGS) $(PACORE_CFLAGS) $(PA_CFLAGS) + module_tizenaudio_sink_la_SOURCES = src/module-tizenaudio-sink.c module_tizenaudio_sink_la_LDFLAGS = $(MODULE_LDFLAGS) module_tizenaudio_sink_la_LIBADD = $(MODULE_LIBADD) libhal-interface.la @@ -88,14 +102,13 @@ module_sound_player_la_CFLAGS = $(MODULE_CFLAGS) $(DBUS_CFLAGS) module_tizenaudio_policy_la_SOURCES = \ src/module-tizenaudio-policy.c \ - src/communicator.c src/communicator.h \ src/stream-manager.c src/stream-manager.h src/stream-manager-priv.h \ src/stream-manager-volume.c src/stream-manager-volume.h src/stream-manager-volume-priv.h \ src/stream-manager-restriction.c src/stream-manager-restriction-priv.h \ src/device-manager.c src/device-manager.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 module_tizenaudio_policy_la_LDFLAGS = $(MODULE_LDFLAGS) -L$(pulsemodlibexecdir) -module_tizenaudio_policy_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(LIBJSON_LIBS) libhal-interface.la +module_tizenaudio_policy_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) $(INIPARSER_LIBS) $(LIBJSON_LIBS) libhal-interface.la libcommunicator.la module_tizenaudio_policy_la_CFLAGS = $(MODULE_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) $(INIPARSER_CFLAGS) $(LIBJSON_CFLAGS) if ENABLE_HALTC @@ -109,3 +122,19 @@ module_hw_keysound_la_SOURCES = src/module-hw-keysound.c module_hw_keysound_la_LDFLAGS = $(MODULE_LDFLAGS) module_hw_keysound_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(VCONF_LIBS) module_hw_keysound_la_CFLAGS = $(MODULE_CFLAGS) $(DBUS_CFLAGS) $(VCONF_CFLAGS) + +if ENABLE_VCONF_HELPER +pulsemodlibexec_LTLIBRARIES += module-vconf.la + +module_vconf_la_SOURCES = src/vconf/module-vconf.c +module_vconf_la_LDFLAGS = $(MODULE_LDFLAGS) +module_vconf_la_LIBADD = $(MODULE_LIBADD) libcommunicator.la +module_vconf_la_CFLAGS = $(MODULE_CFLAGS) -DPA_VCONF_HELPER=\"$(pulselibexecdir)/vconf-helper\" + +pulselibexec_PROGRAMS = vconf-helper + +vconf_helper_SOURCES = src/vconf/vconf-helper.c +vconf_helper_LDFLAGS = $(AM_LDFLAGS) +vconf_helper_LDADD = $(AM_LIBADD) $(GLIB2_LIBS) $(VCONF_LIBS) +vconf_helper_CFLAGS = $(AM_CFLAGS) $(GLIB2_CFLAGS) $(VCONF_CFLAGS) -fPIC -pie +endif diff --git a/configure.ac b/configure.ac index 34b05f8..f578a47 100644 --- a/configure.ac +++ b/configure.ac @@ -337,6 +337,7 @@ AC_CHECK_FUNCS_ONCE([open64]) PKG_CHECK_MODULES(PA, libpulse) AC_SUBST(PA_CFLAGS) AC_SUBST(PA_LIBS) +AC_SUBST(PA_LDFLAGS) PKG_CHECK_MODULES(PACORE, pulsecore) AC_SUBST(PACORE_CFLAGS) @@ -403,6 +404,21 @@ PA_MACHINE_ID_FALLBACK="${localstatedir}/lib/dbus/machine-id" AX_DEFINE_DIR(PA_MACHINE_ID_FALLBACK, PA_MACHINE_ID_FALLBACK, [Fallback machine-id file]) +#### vconf helper support (optional) #### +PKG_CHECK_MODULES(GLIB2, glib-2.0) +AC_SUBST(GLIB2_CFLAGS) +AC_SUBST(GLIB2_LIBS) + +AC_ARG_ENABLE(vconf-helper, AC_HELP_STRING([--enable-vconf-helper], [using vconf-helper]), +[ + case "${enableval}" in + yes) ENABLE_VCONF_HELPER=yes ;; + no) ENABLE_VCONF_HELPER=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-vconf-helper) ;; + esac + ],[ENABLE_VCONF_HELPER=no]) +AM_CONDITIONAL(ENABLE_VCONF_HELPER, test "x$ENABLE_VCONF_HELPER" = "xyes") + ################################### # Output # ################################### diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 9c4f8de..6c7912e 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: 5.0.88 +Version: 5.0.89 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ @@ -13,6 +13,9 @@ BuildRequires: pkgconfig(dbus-1) BuildRequires: pkgconfig(iniparser) BuildRequires: pkgconfig(json-c) BuildRequires: pkgconfig(vconf) +%if "%{?TIZEN_PRODUCT_TV}" == "1" +BuildRequires: pkgconfig(glib-2.0) +%endif BuildRequires: mm-hal-interface BuildRequires: pkgconfig(libpulse) BuildRequires: pkgconfig(pulsecore) @@ -34,6 +37,9 @@ export CFLAGS="%{optflags} -fno-strict-aliasing -DSYSCONFDIR=\\\"%{_sysconfdir}\ export LD_AS_NEEDED=0 %reconfigure --prefix=%{_prefix} \ --disable-static \ +%if "%{?TIZEN_PRODUCT_TV}" == "1" + --enable-vconf-helper +%endif # --enable-haltc %__make %{?_smp_mflags} V=1 @@ -56,4 +62,9 @@ install -m 0644 %SOURCE1 %{buildroot}%{_tmpfilesdir}/pulseaudio.conf %license LICENSE.LGPL-2.1+ %{_libdir}/pulse-5.0/modules/module-*.so %{_libdir}/pulse-5.0/modules/libhal-interface.so +%{_libdir}/pulse-5.0/modules/libcommunicator.so %{_tmpfilesdir}/pulseaudio.conf +%if "%{?TIZEN_PRODUCT_TV}" == "1" +%{_libdir}/pulse-5.0/modules/module-vconf.so +%{_libexecdir}/pulse/vconf-helper +%endif diff --git a/src/communicator.h b/src/communicator.h index 849c6be..985f959 100644 --- a/src/communicator.h +++ b/src/communicator.h @@ -32,6 +32,7 @@ typedef enum pa_communicator_hook { PA_COMMUNICATOR_HOOK_DEVICE_STATE_CHANGED, /* It is fired when a device's state is changed */ PA_COMMUNICATOR_HOOK_EVENT_FULLY_HANDLED, /* It is fired when a event is handled by all subscribers */ PA_COMMUNICATOR_HOOK_UPDATE_INFORMATION, /* It is fired when information should be updated */ + PA_COMMUNICATOR_HOOK_UPDATE_VCONF, /* It is fired when a vconf has updated */ PA_COMMUNICATOR_HOOK_MAX } pa_communicator_hook_t; diff --git a/src/vconf/hook-data.h b/src/vconf/hook-data.h new file mode 100644 index 0000000..d0c0bcc --- /dev/null +++ b/src/vconf/hook-data.h @@ -0,0 +1,65 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 KimJeongYeon + + 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 footizenmodulevconffoo +#define footizenmodulevconffoo + +/* Definition for hooking method */ +typedef struct _hook_call_data_for_vconf_changed { + char *key; + char *value; +} pa_module_vconf_hook_data_for_vconf_changed; + +/* Definitions for vconf prefix items */ +enum { + VCONF_PATH_PREFIX_VOLUME = 0, + /* TODO: TBD */ + VCONF_PATH_PREFIX_MAX +}; + +const char *vconf_prefix[VCONF_PATH_PREFIX_MAX] = { + "file/private/sound/volume/", /**< VCONF_PATH_PREFIX_VOLUME */ + /* TODO: TBD */ +}; + +/* Definitions for vconf items for watching */ +struct vconf_item { + char opcode; + int prefix; + const char *name; + int is_notify; +} vitems[] = { + { 'V', VCONF_PATH_PREFIX_VOLUME, "AD", 0 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "Master", 0 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "MasterHeadphone", 0 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "MasterMuteOn", 0 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "alarm", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "call", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "master", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "media", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "notification", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "ringtone", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "system", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "voice", 1 }, + { 'V', VCONF_PATH_PREFIX_VOLUME, "voip", 1 }, + }; + +#endif diff --git a/src/vconf/module-vconf.c b/src/vconf/module-vconf.c new file mode 100644 index 0000000..0270002 --- /dev/null +++ b/src/vconf/module-vconf.c @@ -0,0 +1,274 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 KimJeongYeon + + Based on module-gconf.c + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../communicator.h" +#include "module-vconf-symdef.h" +#include "hook-data.h" + +PA_MODULE_AUTHOR("KimJeongYeon"); +PA_MODULE_DESCRIPTION("VCONF Adapter"); +PA_MODULE_VERSION(PACKAGE_VERSION); +PA_MODULE_LOAD_ONCE(true); + +#define BUF_MAX 2048 + +struct userdata { + pa_core *core; + pa_module *module; + + pid_t pid; + + int fd; + int fd_type; + pa_io_event *io_event; + + char buf[BUF_MAX]; + size_t buf_fill; + + pa_communicator *comm; +}; + +static int fill_buf(struct userdata *u) { + ssize_t r; + pa_assert(u); + + if (u->buf_fill >= BUF_MAX) { + pa_log_error("read buffer overflow"); + return -1; + } + + if ((r = pa_read(u->fd, u->buf + u->buf_fill, BUF_MAX - u->buf_fill, &u->fd_type)) <= 0) + return -1; + + u->buf_fill += (size_t) r; + return 0; +} + +static int read_byte(struct userdata *u) { + int ret; + pa_assert(u); + + if (u->buf_fill < 1) + if (fill_buf(u) < 0) + return -1; + + ret = u->buf[0]; + pa_assert(u->buf_fill > 0); + u->buf_fill--; + memmove(u->buf, u->buf+1, u->buf_fill); + return ret; +} + +static char *read_string(struct userdata *u) { + pa_assert(u); + + for (;;) { + char *e; + + if ((e = memchr(u->buf, 0, u->buf_fill))) { + char *ret = pa_xstrdup(u->buf); + u->buf_fill -= (size_t) (e - u->buf +1); + memmove(u->buf, e+1, u->buf_fill); + return ret; + } + + if (fill_buf(u) < 0) + return NULL; + } +} + +static int handle_event(struct userdata *u) { + int opcode; + int ret = 0; + + do { + if ((opcode = read_byte(u)) < 0) { + if (errno == EINTR || errno == EAGAIN) + break; + goto fail; + } + + switch (opcode) { + case '!': + /* The helper tool is now initialized */ + ret = 1; + pa_log_info("The helper tool is now initialized."); + break; + + case 'V': + /* fall-through */ + + default: { + /* Default vconf changing events */ + char *key, *value; + pa_module_vconf_hook_data_for_vconf_changed hook_data; + + if (!(key = read_string(u))) + goto fail; + if (!(value = read_string(u))) { + pa_xfree(key); + goto fail; + } + + pa_log_info("Vconf notified. (key:%s, value:%s)", key, value); + + /* Hook msg from vconf helper */ + memset(&hook_data, 0, sizeof(pa_module_vconf_hook_data_for_vconf_changed)); + hook_data.key = key; + hook_data.value = value; + pa_hook_fire(pa_communicator_hook(u->comm, PA_COMMUNICATOR_HOOK_UPDATE_VCONF), &hook_data); + + pa_xfree(key); + pa_xfree(value); + break; + } + } + } while (u->buf_fill > 0 && ret == 0); + + return ret; + +fail: + pa_log_error("Unable to read or parse data from client."); + return -1; +} + +static void io_event_cb( + pa_mainloop_api*a, + pa_io_event* e, + int fd, + pa_io_event_flags_t events, + void *userdata) { + + struct userdata *u = userdata; + + if (handle_event(u) < 0) { + + if (u->io_event) { + u->core->mainloop->io_free(u->io_event); + u->io_event = NULL; + } + + pa_module_unload_request(u->module, true); + } +} + +int pa__init(pa_module *m) { + struct userdata *u; + int r; + + pa_assert(m); + + u = pa_xnew(struct userdata, 1); + u->core = m->core; + u->module = m; + m->userdata = u; + u->pid = (pid_t) -1; + u->fd = -1; + u->fd_type = 0; + u->io_event = NULL; + u->buf_fill = 0; + u->comm = pa_communicator_get(m->core); + + if ((u->fd = pa_start_child_for_read( +#if defined(__linux__) && !defined(__OPTIMIZE__) + pa_run_from_build_tree() ? PA_BUILDDIR "/vconf-helper" : +#endif + PA_VCONF_HELPER, NULL, &u->pid)) < 0) + goto fail; + + u->io_event = m->core->mainloop->io_new( + m->core->mainloop, + u->fd, + PA_IO_EVENT_INPUT, + io_event_cb, + u); + + do { + if ((r = handle_event(u)) < 0) + goto fail; + + /* Read until the client signalled us that it is ready with + * initialization */ + } while (r != 1); + + return 0; + +fail: + pa__done(m); + return -1; +} + +void pa__done(pa_module *m) { + struct userdata *u; + + pa_assert(m); + + if (!(u = m->userdata)) + return; + + if (u->comm) + pa_communicator_unref(u->comm); + + if (u->pid != (pid_t) -1) { + kill(u->pid, SIGTERM); + + for (;;) { + if (waitpid(u->pid, NULL, 0) >= 0) + break; + + if (errno != EINTR) { + pa_log_error("waitpid() failed: %s", pa_cstrerror(errno)); + break; + } + } + } + + if (u->io_event) + m->core->mainloop->io_free(u->io_event); + + if (u->fd >= 0) + pa_close(u->fd); + + pa_xfree(u); +} diff --git a/src/vconf/vconf-helper.c b/src/vconf/vconf-helper.c new file mode 100644 index 0000000..f7f8f41 --- /dev/null +++ b/src/vconf/vconf-helper.c @@ -0,0 +1,112 @@ +/*** + This file is part of PulseAudio. + + Copyright 2016 KimJeongYeon + + Based on gconf-helper.c + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include + +#include "hook-data.h" + +#define VCONF_PATH_MAX 128 + +static void vconf_callback(keynode_t *key, void *data) { + char buf[VCONF_PATH_MAX] = {0,}; + struct vconf_item *vitem = (struct vconf_item *)data; + int idx; + + if (!vitem) + return; + + idx = vitem->prefix; + + if (!strncmp(vconf_keynode_get_name(key), vconf_prefix[idx], strlen(vconf_prefix[idx]))) { + snprintf(buf, sizeof(buf), "%c%s", vitem->opcode, vconf_keynode_get_name(key)); + fprintf(stdout, "%s%c", buf, 0); /* Send opcode + key + '\0'. */ + + switch (vconf_keynode_get_type(key)) { + case VCONF_TYPE_STRING: + snprintf(buf, sizeof(buf), "%s", vconf_keynode_get_str(key)); + break; + case VCONF_TYPE_INT: + snprintf(buf, sizeof(buf), "%d", vconf_keynode_get_int(key)); + break; + case VCONF_TYPE_DOUBLE: + snprintf(buf, sizeof(buf), "%f", vconf_keynode_get_dbl(key)); + break; + case VCONF_TYPE_BOOL: + snprintf(buf, sizeof(buf), "%d", vconf_keynode_get_bool(key)); + break; + default: + buf[0] = 0; + break; + } + fprintf(stdout, "%s%c", buf, 0); /* Send value + '\0'. */ + } + + fflush(stdout); +} + +int main(int argc, char *argv[]) { + GMainLoop *g; + char vitem_key[VCONF_PATH_MAX] = {0,}; + int i, idx; + +#if !defined(GLIB_VERSION_2_36) + g_type_init(); +#endif + + /* Register vconf changing handler */ + for (i = 0; i < sizeof(vitems) / sizeof(vitems[0]); i++) { + if (vitems[i].is_notify) { + idx = vitems[i].prefix; + snprintf(vitem_key, sizeof(vitem_key), "%s%s", vconf_prefix[idx], vitems[i].name); + vconf_notify_key_changed(vitem_key, vconf_callback, &vitems[i]); + } + } + + /* Signal the parent that we are now initialized */ + fprintf(stdout, "!"); + fflush(stdout); + + g = g_main_loop_new(NULL, FALSE); + g_main_loop_run(g); + g_main_loop_unref(g); + + /* Unregister vconf changing handler */ + for (i = 0; i < sizeof(vitems) / sizeof(vitems[0]); i++) { + if (vitems[i].is_notify) { + idx = vitems[i].prefix; + snprintf(vitem_key, sizeof(vitem_key), "%s%s", vconf_prefix[idx], vitems[i].name); + vconf_ignore_key_changed(vitem_key, vconf_callback); + } + } + + return 0; +} -- 2.7.4 From 49d9ea95023eda705f3c2f1a47c0a05b14a89ea4 Mon Sep 17 00:00:00 2001 From: KimJeongYeon Date: Mon, 7 Nov 2016 17:09:35 +0900 Subject: [PATCH 13/16] tizenaudio-sink/source: Remove unused parameters [Version] 5.0.90 [Profile] Common [Issue Type] Miscellaneous Signed-off-by: KimJeongYeon Change-Id: I6802cead9e296c85901dae8e0f0dbe04d2ed931b --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-sink.c | 14 ++------------ src/module-tizenaudio-source.c | 14 ++------------ 3 files changed, 5 insertions(+), 25 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 6c7912e..5bf79a1 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: 5.0.89 +Version: 5.0.90 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-sink.c b/src/module-tizenaudio-sink.c index 99ae7f6..3b581c7 100644 --- a/src/module-tizenaudio-sink.c +++ b/src/module-tizenaudio-sink.c @@ -1,7 +1,7 @@ /*** This file is part of PulseAudio. - Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved. PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published @@ -53,12 +53,8 @@ PA_MODULE_DESCRIPTION("Tizen Audio Sink"); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(false); PA_MODULE_USAGE( - "name= " "sink_name= " "sink_properties= " - "namereg_fail= " - "device= " - "device_id= " "format= " "rate= " "channels= " @@ -88,7 +84,6 @@ struct userdata { pa_usec_t timestamp; pa_usec_t timestamp_written; - char* device_name; bool first; pa_rtpoll_item *rtpoll_item; @@ -98,12 +93,8 @@ struct userdata { }; static const char* const valid_modargs[] = { - "name", "sink_name", "sink_properties", - "namereg_fail", - "device", - "device_id", "format", "rate", "channels", @@ -155,7 +146,7 @@ static int suspend(struct userdata *u) { u->rtpoll_item = NULL; } - pa_log_info("Device suspended...[%s]", u->device_name); + pa_log_info("Device suspended..."); return 0; } @@ -215,7 +206,6 @@ static int sink_process_msg( pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state)); if ((r = suspend(u)) < 0) return r; - break; } diff --git a/src/module-tizenaudio-source.c b/src/module-tizenaudio-source.c index 0578cc0..c60f90b 100644 --- a/src/module-tizenaudio-source.c +++ b/src/module-tizenaudio-source.c @@ -1,7 +1,7 @@ /*** This file is part of PulseAudio. - Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved. PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published @@ -53,12 +53,8 @@ PA_MODULE_DESCRIPTION("Tizen Audio Source"); PA_MODULE_VERSION(PACKAGE_VERSION); PA_MODULE_LOAD_ONCE(false); PA_MODULE_USAGE( - "name= " "source_name= " "source_properties= " - "namereg_fail= " - "device= " - "device_id= " "format= " "rate= " "channels= " @@ -88,7 +84,6 @@ struct userdata { pa_usec_t block_usec; pa_usec_t timestamp; - char* device_name; bool first; pa_rtpoll_item *rtpoll_item; @@ -99,12 +94,8 @@ struct userdata { }; static const char* const valid_modargs[] = { - "name", "source_name", "source_properties", - "namereg_fail", - "device", - "device_id", "format", "rate", "channels", @@ -156,7 +147,7 @@ static int suspend(struct userdata *u) { u->rtpoll_item = NULL; } - pa_log_info("Device suspended...[%s]", u->device_name); + pa_log_info("Device suspended..."); return 0; } @@ -216,7 +207,6 @@ static int source_process_msg( pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state)); if ((r = suspend(u)) < 0) return r; - break; } -- 2.7.4 From d55e9161e068f44e672c786fb352ccb94c179542 Mon Sep 17 00:00:00 2001 From: Jeongho Mok Date: Mon, 7 Nov 2016 19:15:11 +0900 Subject: [PATCH 14/16] Match both direction device with direction in or out mask [Version] 5.0.91 [Profile] Common [Issue Type] Policy Change-Id: I3875b62ca85388236a68e518b95d7593336ae0f4 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/device-manager.c | 125 +++++++++++++++++++------------- 2 files changed, 77 insertions(+), 50 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 5bf79a1..698916f 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: 5.0.90 +Version: 5.0.91 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/device-manager.c b/src/device-manager.c index f0f3b96..a386729 100644 --- a/src/device-manager.c +++ b/src/device-manager.c @@ -430,6 +430,11 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = { #endif +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, int avail_mode) { + pa_logl(level, "%s device id(%d) type(%s) name (%s) direction(%d) state(%d) avail-mode(%d)", + pa_strempty(prefix), id, pa_strnull(type), pa_strnull(name), direction, state, avail_mode); +} + static void type_info_free_func(struct device_type_info *type_info) { if (!type_info) return; @@ -2617,7 +2622,7 @@ static int _get_avail_mode(pa_tz_device *device) { return avail_mode; } -static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device, bool connected, pa_device_manager *dm) { +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, device_iter; dbus_bool_t _connected = connected; @@ -2628,8 +2633,7 @@ static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device pa_assert(device); pa_assert(dm); - pa_log_info("Send device %s signal, event_id(%u) device(%u)", - connected ? "Connected" : "Disconnected", event_id, device->id); + 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); @@ -2640,9 +2644,11 @@ static void send_device_connected_signal(uint32_t event_id, pa_tz_device *device type = pa_tz_device_get_type(device); name = pa_tz_device_get_name(device); avail_mode = _get_avail_mode(device); - device_id = (dbus_int32_t) pa_tz_device_get_id(device); compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); + + simple_device_dump(PA_LOG_INFO, connected ? "[Connected]" : "[Disconnected]", device_id, type, name, direction, compound_state, avail_mode); + 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); @@ -2663,12 +2669,12 @@ static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *dev dm_device_state_t compound_state; dbus_int32_t device_id, direction, avail_mode; char *type, *name; + 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) device(%u) changed_type(%d)", - event_id, device->id, changed_type); + 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); @@ -2682,6 +2688,8 @@ static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *dev compound_state = pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH); avail_mode = (dbus_int32_t) _get_avail_mode(device); + simple_device_dump(PA_LOG_DEBUG, changed_prefix[changed_type], device_id, type, name, direction, compound_state, avail_mode); + 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); @@ -2696,55 +2704,69 @@ static void send_device_info_changed_signal(uint32_t event_id, pa_tz_device *dev dbus_message_unref(signal_msg); } -static bool device_item_match_for_mask(pa_tz_device *device, int device_flags, pa_device_manager *dm) { - bool match = false; - int need_to_check_for_io_direction = device_flags & DEVICE_IO_DIRECTION_FLAGS; - int need_to_check_for_state = device_flags & DEVICE_STATE_FLAGS; - int need_to_check_for_type = device_flags & DEVICE_TYPE_FLAGS; +static bool device_is_match_direction(pa_tz_device *device, int direction_mask) { dm_device_direction_t direction; - char *type; - pa_assert(device); - - if (device_flags == DEVICE_ALL_FLAG) + 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, DM_DEVICE_DIRECTION_BOTH); + + 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 (need_to_check_for_io_direction) { - if ((direction == DM_DEVICE_DIRECTION_IN) && (device_flags & DEVICE_IO_DIRECTION_IN_FLAG)) match = true; - else if ((direction == DM_DEVICE_DIRECTION_OUT) && (device_flags & DEVICE_IO_DIRECTION_OUT_FLAG)) match = true; - else if ((direction == DM_DEVICE_DIRECTION_BOTH) && (device_flags & DEVICE_IO_DIRECTION_BOTH_FLAG)) match = true; - if (match) { - if (!need_to_check_for_state && !need_to_check_for_type) return true; - } else { - return false; - } - } - if (need_to_check_for_state) { - match = false; - if ((pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH) == DM_DEVICE_STATE_DEACTIVATED) && (device_flags & DEVICE_STATE_DEACTIVATED_FLAG)) - match = true; - else if ((pa_tz_device_get_state(device, DM_DEVICE_DIRECTION_BOTH) == DM_DEVICE_STATE_ACTIVATED) && (device_flags & DEVICE_STATE_ACTIVATED_FLAG)) - match = true; - if (match) { - if (!need_to_check_for_type) - return true; - } else { - return false; - } - } - if (need_to_check_for_type) { - if (device_type_is_builtin(type) && (device_flags & DEVICE_TYPE_INTERNAL_FLAG)) - return true; - else if (!device_type_is_builtin(type) && (device_flags & DEVICE_TYPE_EXTERNAL_FLAG)) - return true; - } + 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; @@ -2798,23 +2820,24 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * dm_device_state_t compound_state; uint32_t device_idx; dbus_int32_t device_id, direction, avail_mode; - int mask_flags; + int mask; char *type, *name; pa_assert(conn); pa_assert(msg); pa_assert(userdata); - pa_log_info("Get connected device list"); dm = (pa_device_manager*) userdata; pa_assert_se((reply = dbus_message_new_method_return(msg))); pa_assert_se(dbus_message_get_args(msg, NULL, - DBUS_TYPE_INT32, &mask_flags, + DBUS_TYPE_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, "(isiiis)", &array_iter)); @@ -2824,8 +2847,10 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * type = pa_tz_device_get_type(device); name = pa_tz_device_get_name(device); avail_mode = _get_avail_mode(device); - if (device_item_match_for_mask(device, mask_flags, dm)) { + if (device_is_match_with_mask(device, mask)) { device_id = (dbus_int32_t)pa_tz_device_get_id(device); + + simple_device_dump(PA_LOG_INFO, "[MATCH]", device_id, type, name, direction, compound_state, avail_mode); 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); @@ -2834,6 +2859,8 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage * dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_INT32, &avail_mode); dbus_message_iter_append_basic(&device_iter, DBUS_TYPE_STRING, &name); 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, compound_state, avail_mode); } } @@ -3233,7 +3260,7 @@ fail: } static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_device_hook_data_for_conn_changed *data, pa_device_manager *dm) { - send_device_connected_signal(data->event_id, data->device, data->is_connected, dm); + send_device_connection_changed_signal(data->event_id, data->device, data->is_connected, dm); return PA_HOOK_OK; } -- 2.7.4 From 0917f15e665e6ea2e2289d1a13f277cf8e8a2c0f Mon Sep 17 00:00:00 2001 From: Hyunseok Lee Date: Wed, 2 Nov 2016 19:02:44 +0900 Subject: [PATCH 15/16] Fix SVACE critical issues [Version] 5.0.92 [Profile] Common [Issue Type] CleanUp Change-Id: I9525604e746470c23085eab9346326a60d2eadf5 --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/module-tizenaudio-policy.c | 16 +++++++++------- src/stream-manager.c | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 698916f..58cccd2 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: 5.0.91 +Version: 5.0.92 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/module-tizenaudio-policy.c b/src/module-tizenaudio-policy.c index ab8c673..b51798b 100644 --- a/src/module-tizenaudio-policy.c +++ b/src/module-tizenaudio-policy.c @@ -766,16 +766,18 @@ static pa_hook_result_t route_change_hook_cb(pa_core *c, pa_stream_manager_hook_ /* move sink-inputs/source-outputs if needed */ if (data->stream_type == STREAM_SINK_INPUT) - sink = pa_tz_device_get_sink(device, data->device_role); - /* unload combine sink */ if (data->stream_type == STREAM_SINK_INPUT && u->module_combine_sink) { if ((combine_sink = (pa_sink*)pa_namereg_get(u->core, SINK_NAME_COMBINED, PA_NAMEREG_SINK))) { - PA_IDXSET_FOREACH(s, combine_sink->inputs, s_idx) { - pa_sink_input_move_to(s, sink, false); - pa_log_debug("[ROUTE][AUTO] *** sink-input(%p,%u) moves to sink(%p,%s)", - s, ((pa_sink_input*)s)->index, sink, sink->name); - } + if ((sink = pa_tz_device_get_sink(device, data->device_role))) { + PA_IDXSET_FOREACH(s, combine_sink->inputs, s_idx) { + pa_sink_input_move_to(s, sink, false); + pa_log_debug("[ROUTE][AUTO] *** sink-input(%p,%u) moves to sink(%p,%s)", + s, ((pa_sink_input*)s)->index, sink, sink->name); + } + } else + pa_log_error("[ROUTE][AUTO] could not get sink"); + pa_sink_suspend(combine_sink, true, PA_SUSPEND_USER); } else pa_log_error("[ROUTE][AUTO] could not get combine_sink"); diff --git a/src/stream-manager.c b/src/stream-manager.c index 37badeb..738032f 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -2177,7 +2177,7 @@ static void fill_device_info_to_hook_data(pa_stream_manager *m, void *hook_data, pa_log_debug(" -- could not get the parent id of this stream, but keep going..."); } } else - pa_log_error(" -- could not find (%s)", route_data->stream_role); + pa_log_error(" -- could not find (%s)", select_data->stream_role); break; } -- 2.7.4 From ddab5639697fd8450a21d3e8afca34cf321079cc Mon Sep 17 00:00:00 2001 From: Sangchul Lee Date: Thu, 10 Nov 2016 12:55:37 +0900 Subject: [PATCH 16/16] stream-manager: Add condition to set active-dev prop. only if it is auto/audio-last-connected routing type The condition is added in update_the_highest_priority_stream() Use a static function instead of macro to set new data stream to null sink(source) [Version] 5.0.93 [Profile] Common [Issue Type] Feature Enhancement Change-Id: I24e14bdd182da3acfc6374a649a5826ba30b445e Signed-off-by: Sangchul Lee --- packaging/pulseaudio-modules-tizen.spec | 2 +- src/stream-manager.c | 58 ++++++++++++++++++--------------- src/stream-manager.h | 3 ++ 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/packaging/pulseaudio-modules-tizen.spec b/packaging/pulseaudio-modules-tizen.spec index 58cccd2..0e8bd6a 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: 5.0.92 +Version: 5.0.93 Release: 0 Group: Multimedia/Audio License: LGPL-2.1+ diff --git a/src/stream-manager.c b/src/stream-manager.c index 738032f..d10b859 100644 --- a/src/stream-manager.c +++ b/src/stream-manager.c @@ -462,24 +462,6 @@ typedef struct _stream_route_option { x_device_role = DEVICE_ROLE_NORMAL; \ } \ -#define SET_NEW_DATA_STREAM_TO_NULL_SINK_SOURCE(x_m, x_stream, x_stream_type) { \ - pa_sink *null_sink; \ - pa_source *null_source; \ - if (x_stream_type == STREAM_SINK_INPUT && \ - (!((pa_sink_input_new_data*)x_stream)->sink)) { \ - if ((null_sink = (pa_sink*)pa_namereg_get(x_m->core, SINK_NAME_NULL, PA_NAMEREG_SINK))) \ - ((pa_sink_input_new_data*)x_stream)->sink = null_sink; \ - else \ - pa_log_warn("could not get null_sink"); \ - } else if (x_stream_type == STREAM_SOURCE_OUTPUT && \ - (!((pa_source_output_new_data*)x_stream)->source)) { \ - if ((null_source = (pa_source*)pa_namereg_get(x_m->core, SOURCE_NAME_NULL, PA_NAMEREG_SOURCE))) \ - ((pa_source_output_new_data*)x_stream)->source = null_source; \ - else \ - pa_log_warn("could not get null_source"); \ - } \ -} \ - static void do_notify(pa_stream_manager *m, notify_command_type_t command, stream_type_t type, bool is_new_data, void *user_data); static process_stream_result_t process_stream(pa_stream_manager *m, void *stream, stream_type_t type, process_command_type_t command, bool is_new_data); @@ -1950,11 +1932,13 @@ static bool update_the_highest_priority_stream(pa_stream_manager *m, process_com } else { /* no need to trigger, * update active device info if possible */ - if ((active_dev = pa_proplist_gets(GET_STREAM_PROPLIST(cur_max_stream, type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV))) { - if (is_new_data) - pa_proplist_sets(GET_STREAM_NEW_PROPLIST(mine, type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, active_dev); - else - pa_proplist_sets(GET_STREAM_PROPLIST(mine, type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, active_dev); + if (IS_ROUTE_TYPE_FOR_AUTO(route_type_str, route_type) || IS_ROUTE_TYPE_FOR_AUTO_LAST_CONN(route_type_str, route_type)) { + if ((active_dev = pa_proplist_gets(GET_STREAM_PROPLIST(cur_max_stream, type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV))) { + if (is_new_data) + pa_proplist_sets(GET_STREAM_NEW_PROPLIST(mine, type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, active_dev); + else + pa_proplist_sets(GET_STREAM_PROPLIST(mine, type), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, active_dev); + } } return true; } @@ -2408,6 +2392,26 @@ static int update_forwarding_device(pa_stream_manager *m, bool load) { return 0; } +static void set_new_data_stream_to_null_sink_source(pa_stream_manager *m, void *stream, stream_type_t type) { + pa_sink *null_sink; + pa_source *null_source; + + pa_assert(m); + pa_assert(stream); + + if (type == STREAM_SINK_INPUT && !((pa_sink_input_new_data*)stream)->sink) { + if ((null_sink = (pa_sink*)pa_namereg_get(m->core, SINK_NAME_NULL, PA_NAMEREG_SINK))) + ((pa_sink_input_new_data*)stream)->sink = null_sink; + else + pa_log_warn("could not get null_sink"); + } else if (type == STREAM_SOURCE_OUTPUT && !((pa_source_output_new_data*)stream)->source) { + if ((null_source = (pa_source*)pa_namereg_get(m->core, SOURCE_NAME_NULL, PA_NAMEREG_SOURCE))) + ((pa_source_output_new_data*)stream)->source = null_source; + else + pa_log_warn("could not get null_source"); + } +} + static process_stream_result_t process_stream(pa_stream_manager *m, void *stream, stream_type_t type, process_command_type_t command, bool is_new_data) { process_stream_result_t result = PROCESS_STREAM_RESULT_OK; const char *role = NULL; @@ -2435,7 +2439,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream result = PROCESS_STREAM_RESULT_SKIP; /* set it to null sink/source */ if (is_new_data) - SET_NEW_DATA_STREAM_TO_NULL_SINK_SOURCE(m, stream, type); + set_new_data_stream_to_null_sink_source(m, stream, type); goto finish; } @@ -2515,7 +2519,7 @@ static process_stream_result_t process_stream(pa_stream_manager *m, void *stream pa_log_debug("skip notifying for selecting sink/source, rather set it to null sink/source"); /* set it to null sink/source */ if (is_new_data) - SET_NEW_DATA_STREAM_TO_NULL_SINK_SOURCE(m, stream, type); + set_new_data_stream_to_null_sink_source(m, stream, type); } else { /* notify to select sink or source */ @@ -3408,7 +3412,7 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi ((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 */ active_dev = pa_proplist_gets(GET_STREAM_PROPLIST(s, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV); - if (active_dev && pa_streq(active_dev, device_type)) + if (pa_safe_streq(active_dev, device_type)) pa_proplist_sets(GET_STREAM_PROPLIST(s, STREAM_SOURCE_OUTPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, ACTIVE_DEV_REMOVED); } } @@ -3432,7 +3436,7 @@ static pa_hook_result_t device_connection_changed_hook_cb(pa_core *c, pa_tz_devi ((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 */ active_dev = pa_proplist_gets(GET_STREAM_PROPLIST(s, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV); - if (active_dev && pa_streq(active_dev, device_type)) + if (pa_safe_streq(active_dev, device_type)) pa_proplist_sets(GET_STREAM_PROPLIST(s, STREAM_SINK_INPUT), PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, ACTIVE_DEV_REMOVED); } } diff --git a/src/stream-manager.h b/src/stream-manager.h index b90d65b..4779fc7 100644 --- a/src/stream-manager.h +++ b/src/stream-manager.h @@ -30,6 +30,9 @@ #define IS_ROUTE_TYPE_FOR_AUTO(route_type_str, route_type) \ (route_type_str && !pa_atoi(route_type_str, (int32_t*)&route_type) && (route_type == STREAM_ROUTE_TYPE_AUTO)) +#define IS_ROUTE_TYPE_FOR_AUTO_LAST_CONN(route_type_str, route_type) \ + (route_type_str && !pa_atoi(route_type_str, (int32_t*)&route_type) && (route_type == STREAM_ROUTE_TYPE_AUTO_LAST_CONNECTED)) + #define GET_STREAM_NEW_PROPLIST(stream, type) \ (type == STREAM_SINK_INPUT ? ((pa_sink_input_new_data*)stream)->proplist : ((pa_source_output_new_data*)stream)->proplist) -- 2.7.4