Name: pulseaudio-modules-tizen
Summary: Pulseaudio modules for Tizen
-Version: 13.0.70
+Version: 13.0.71
Release: 0
Group: Multimedia/Audio
License: LGPL-2.1+
export CFLAGS="%{optflags} -fno-strict-aliasing -D__TIZEN__ -DSYSCONFDIR=\\\"%{_hal_sysconfdir}\\\" "
%if "%{tizen_profile_name}" == "tv"
export CFLAGS+=" -DTIZEN_TV";
+%else
+ export CFLAGS+=" -D__TIZEN_INTERNAL_BT_SCO__"
%endif
export LD_AS_NEEDED=0
static void handle_test_device_status_change(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_set_acm_mode(DBusConnection *conn, DBusMessage *msg, void *userdata);
+#ifdef __TIZEN_INTERNAL_BT_SCO__
static int method_call_bt_get_name(DBusConnection *conn, const char *device_path, char **name);
+#endif
enum method_handler_index {
METHOD_HANDLER_GET_CONNECTED_DEVICE_LIST,
return 0;
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
static int handle_bluez_headset_property_changed(DBusConnection *c, DBusMessage *s, pa_device_manager *dm) {
DBusMessageIter msg_iter, variant_iter;
char *property_name;
return 0;
}
+#endif /* __TIZEN_INTERNAL_BT_SCO__ */
static DBusHandlerResult dbus_filter_device_detect_handler(DBusConnection *c, DBusMessage *s, void *userdata) {
DBusError error;
goto fail;
}
handle_device_status_changed(dm, DEVICE_TYPE_FORWARDING, NULL, NULL, detected);
-
+#ifdef __TIZEN_INTERNAL_BT_SCO__
} else if (dbus_message_is_signal(s, DBUS_INTERFACE_BLUEZ_HEADSET, "PropertyChanged")) {
if (handle_bluez_headset_property_changed(c, s, dm) < 0)
goto fail;
-
+#endif
} else {
pa_log_debug("Unknown message, not handle it");
dbus_error_free(&error);
device_is_match_type(device, mask & DEVICE_TYPE_FLAGS));
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
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;
dbus_message_unref(reply);
return 0;
}
+#endif /* __TIZEN_INTERNAL_BT_SCO__ */
static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *msg, void *userdata) {
pa_device_manager *dm = (pa_device_manager *)userdata;
#define DEVICE_API_RAOP "raop"
#define DEVICE_API_TUNNEL "tunnel"
#define DEVICE_API_RTSP "rtsp"
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+#define DEVICE_API_BTSCO "btsco"
+#endif
#define DEVICE_BUS_USB "usb"
#define DEVICE_CLASS_SOUND "sound"
#define DEVICE_CLASS_MONITOR "monitor"
return pa_safe_streq(pa_proplist_gets(prop, PA_PROP_DEVICE_API), DEVICE_API_RTSP);
}
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+static bool pulse_device_is_btsco(pa_object *pdevice) {
+ pa_proplist *prop = pulse_device_get_proplist(pdevice);
+
+ if (!prop)
+ return false;
+
+ return pa_safe_streq(pa_proplist_gets(prop, PA_PROP_DEVICE_API), DEVICE_API_BTSCO);
+}
+#endif
+
static const char* pulse_device_get_device_string_removed_argument(pa_object *pdevice) {
static char removed_param[DEVICE_PARAM_STRING_MAX] = {0,};
char *device_string_p = NULL;
return pa_proplist_gets(prop, PA_PROP_DEVICE_DESCRIPTION);
else if (pulse_device_is_rtsp(pdevice))
return pa_proplist_gets(prop, PA_PROP_DEVICE_DESCRIPTION);
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+ else if (pulse_device_is_btsco(pdevice))
+ return pa_proplist_gets(prop, PA_PROP_DEVICE_DESCRIPTION);
+#endif
else
return NULL;
}
}
}
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+static void handle_external_btsco_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *dm) {
+ const char *name, *system_id;
+ dm_device_direction_t direction;
+ pa_tz_device *device;
+
+ pa_assert(pdevice);
+ pa_assert(dm);
+
+ pa_log_info("Handle btsco pulse device");
+
+ system_id = pulse_device_get_system_id(pdevice);
+ direction = pulse_device_get_direction(pdevice);
+
+ if (is_loaded) {
+ pa_tz_device_new_data data;
+ pa_proplist *prop;
+
+ prop = pulse_device_get_proplist(pdevice);
+ name = pa_proplist_gets(prop, PA_PROP_DEVICE_DESCRIPTION);
+
+ pa_tz_device_new_data_init(&data, dm->device_list, dm->comm, NULL);
+ pa_tz_device_new_data_set_type(&data, DEVICE_TYPE_BT_SCO);
+ pa_tz_device_new_data_set_name(&data, name);
+ pa_tz_device_new_data_set_direction(&data, direction);
+ pa_tz_device_new_data_set_system_id(&data, system_id);
+ pa_tz_device_new_data_set_use_internal_codec(&data, false);
+ if (direction == DM_DEVICE_DIRECTION_OUT) {
+ pa_tz_device_new_data_add_sink(&data, DEVICE_ROLE_NORMAL, PA_SINK(pdevice));
+ } else {
+ pa_tz_device_new_data_add_source(&data, DEVICE_ROLE_NORMAL, PA_SOURCE(pdevice));
+ }
+
+ pa_tz_device_new(&data);
+ pa_tz_device_new_data_done(&data);
+ } else {
+ if (!(device = device_list_get_device(dm, DEVICE_TYPE_BT_SCO, NULL, system_id)))
+ pa_log_warn("Can't get btsco device for %s", system_id);
+ else
+ pa_tz_device_free(device);
+ }
+}
+#endif /* __TIZEN_INTERNAL_BT_SCO__ */
+
static void handle_internal_pulse_device(pa_object *pdevice, bool is_loaded, pa_device_manager *dm) {
pa_tz_device *device;
struct composite_type *ctype;
pulse_device_set_use_internal_codec(PA_OBJECT(sink), true);
handle_internal_pulse_device(PA_OBJECT(sink), true, dm);
return PA_HOOK_OK;
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+ } else if (pulse_device_is_btsco(PA_OBJECT(sink))) {
+ pulse_device_set_use_internal_codec(PA_OBJECT(sink), false);
+ handle_external_btsco_pulse_device(PA_OBJECT(sink), true, dm);
+ return PA_HOOK_OK;
+#endif
} else {
pa_log_debug("Don't care this sink");
}
} else if (pulse_device_is_alsa(PA_OBJECT(sink)) || pulse_device_is_tizenaudio(PA_OBJECT(sink))) {
handle_internal_pulse_device(PA_OBJECT(sink), false, dm);
return PA_HOOK_OK;
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+ } else if (pulse_device_is_btsco(PA_OBJECT(sink))) {
+ handle_external_btsco_pulse_device(PA_OBJECT(sink), false, dm);
+ return PA_HOOK_OK;
+#endif
} else {
pa_log_debug("Don't care this sink");
}
pulse_device_set_use_internal_codec(PA_OBJECT(source), false);
handle_rtsp_pulse_device(PA_OBJECT(source), true, dm);
return PA_HOOK_OK;
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+ } else if (pulse_device_is_btsco(PA_OBJECT(source))) {
+ pulse_device_set_use_internal_codec(PA_OBJECT(source), false);
+ handle_external_btsco_pulse_device(PA_OBJECT(source), true, dm);
+#endif
} else {
pa_log_debug("Don't care this source");
}
return PA_HOOK_OK;
} else if (pulse_device_is_rtsp(PA_OBJECT(source))) {
handle_rtsp_pulse_device(PA_OBJECT(source), false, dm);
+#ifndef __TIZEN_INTERNAL_BT_SCO__
+ } else if (pulse_device_is_btsco(PA_OBJECT(source))) {
+ handle_external_btsco_pulse_device(PA_OBJECT(source), false, dm);
return PA_HOOK_OK;
+#endif
} else {
pa_log_debug("Don't care this source");
}
#define LOOPBACK_DEFAULT_LATENCY_MSEC 40
#define LOOPBACK_DEFAULT_ADJUST_SEC 3
+#ifdef __TIZEN_INTERNAL_BT_SCO__
#define TIMED_BT_SCO_CLOSE_USEC 3000000
+#endif
/* Macros */
#define CONVERT_TO_HAL_DIRECTION(stream_type) \
int32_t latency_msec;
int32_t adjust_sec;
} loopback_args;
+#ifdef __TIZEN_INTERNAL_BT_SCO__
pa_time_event *time_event_bt_sco_close;
+#endif
};
static void __load_dump_config(struct userdata *u)
iniparser_freedict(dict);
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
/* threre is only one sco connected device */
static pa_tz_device* _get_sco_connected_device(pa_device_manager *dm) {
pa_idxset *device_list;
pa_log_warn("Failed to get property for wideband / nrec....");
}
}
+#endif
static void update_loopback_module_args(struct userdata* u, int32_t parent_id, pa_sink *sink, pa_source *source)
{
return false;
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
static bool skip_bt_sco_device(struct userdata *u, const char *stream_role, const char *device_type) {
pa_assert(u);
pa_assert(stream_role);
return false;
}
+#endif
static bool is_supported_stream_role_for_usb(const char *role) {
pa_assert(role);
if (!pa_safe_streq(device_type, dm_device_type) || !IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction))
continue;
pa_log_info(" ** found a matched device: type[%-16s], direction[0x%x]", dm_device_type, dm_device_direction);
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (skip_bt_sco_device(u, data->stream_role, dm_device_type))
continue;
+#endif
if (skip_usb_device(data->stream_role, device))
continue;
dm_device_type, dm_device_direction, dm_device_id, creation_time);
if (!pa_safe_streq(device_type, dm_device_type) || !IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction))
continue;
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (skip_bt_sco_device(u, data->stream_role, dm_device_type))
continue;
+#endif
if (skip_usb_device(data->stream_role, device))
continue;
pa_assert(u);
+#ifdef __TIZEN_INTERNAL_BT_SCO__
/* update BT SCO: close */
update_bt_sco_state(u, false, true, NULL);
+#endif
/* unload combine sink */
if (stream_type == STREAM_SINK_INPUT) {
route_info->num_of_devices -1, type, direction, id);
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
static pa_hook_result_t update_combine_sink_and_bt_sco(struct userdata *u, pa_stream_manager_hook_data_for_route *data,
pa_tz_device *device, const char *stream_role, const char *dm_device_type,
pa_sink **combine_sink_arg1, pa_sink **combine_sink_arg2) {
+#else
+static pa_hook_result_t update_combine_sink(struct userdata *u, pa_stream_manager_hook_data_for_route *data,
+ pa_tz_device *device, const char *stream_role, const char *dm_device_type,
+ pa_sink **combine_sink_arg1, pa_sink **combine_sink_arg2) {
+#endif
pa_sink *sink = NULL;
pa_assert(u);
else
pa_log_error("[ROUTE][AUTO] could not get sink");
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (pa_safe_streq(dm_device_type, DEVICE_TYPE_BT_SCO)) {
if (IS_ROLE_AVAILABLE_BT_SCO_OPEN(stream_role)) {
if (update_bt_sco_state(u, true, false, stream_role)) {
return PA_HOOK_OK;
}
update_bt_sco_state(u, false, false, NULL);
+#endif
break;
}
case STREAM_ROUTE_TYPE_AUTO_ALL: {
void *s = NULL;
stream_route_type_t route_type;
+#ifdef __TIZEN_INTERNAL_BT_SCO__
update_bt_sco_state(u, false, false, NULL);
+#endif
/* find the proper sink/source */
/* currently, we support two sinks for combining */
/* if it needs to skip it, keep going to next device for proper UCM setting */
if (skip_device(data->stream_role, dm_device_type))
return -1;
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (skip_bt_sco_device(u, data->stream_role, dm_device_type))
return -1;
+#endif
fill_device_info(route_info, dm_device_type, CONVERT_TO_HAL_DIRECTION(data->stream_type), dm_device_id);
return 0;
}
/* 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;
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (skip_bt_sco_device(u, data->stream_role, dm_device_type))
continue;
+#endif
fill_device_info(route_info, dm_device_type, CONVERT_TO_HAL_DIRECTION(data->stream_type), dm_device_id);
break;
}
else
pa_proplist_sets(GET_STREAM_PROPLIST(data->stream, data->stream_type),
PA_PROP_MEDIA_ROUTE_AUTO_ACTIVE_DEV, dm_device_type);
+#ifdef __TIZEN_INTERNAL_BT_SCO__
return update_combine_sink_and_bt_sco(u, data, *device, route_info->role, dm_device_type, NULL, NULL);
+#else
+ return update_combine_sink(u, data, *device, route_info->role, dm_device_type, NULL, NULL);
+#endif
} else if (data->route_type == STREAM_ROUTE_TYPE_AUTO_ALL) {
+#ifdef __TIZEN_INTERNAL_BT_SCO__
update_combine_sink_and_bt_sco(u, data, *device, NULL, NULL, &combine_sink_arg1, &combine_sink_arg2);
+#else
+ update_combine_sink(u, data, *device, NULL, NULL, &combine_sink_arg1, &combine_sink_arg2);
+#endif
}
}
return PA_HOOK_OK;
continue;
if ((use_internal_codec = pa_tz_device_is_use_internal_codec(*device))) {
/* if it needs to skip it, keep going to next device for proper UCM setting */
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (skip_device(data->stream_role, dm_device_type) ||
skip_bt_sco_device(u, data->stream_role, dm_device_type))
+#else
+ if (skip_device(data->stream_role, dm_device_type))
+#endif
continue;
}
if (!latest_device || (latest_creation_time <= creation_time)) {
pa_log_error("[ROUTE][AUTO_LAST_CONN] could not get sink");
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (pa_safe_streq(dm_device_type, DEVICE_TYPE_BT_SCO)) {
if (IS_ROLE_AVAILABLE_BT_SCO_OPEN(route_info->role)) {
if (update_bt_sco_state(u, true, false, route_info->role)) {
} else {
update_bt_sco_state(u, false, false, NULL);
}
+#endif
/* Update device with latest_device to use be used later in this function */
*device = latest_device;
dm_device_direction = pa_tz_device_get_direction(*device);
pa_log_debug(" ** found a matched device: type[%-16s], direction[0x%x]",
dm_device_type, dm_device_direction);
+
+#ifdef __TIZEN_INTERNAL_BT_SCO__
/* Check for availability for opening Bluetooth SCO */
if (pa_safe_streq(dm_device_type, DEVICE_TYPE_BT_SCO) && IS_ROLE_AVAILABLE_BT_SCO_OPEN(route_info->role)) {
/* update BT SCO: open */
/* update BT SCO: close */
update_bt_sco_state(u, false, false, NULL);
}
+#endif
if (IS_AVAILABLE_DIRECTION(data->stream_type, dm_device_direction)) {
if ((use_internal_codec = pa_tz_device_is_use_internal_codec(*device)))
if (!(u = m->userdata))
return;
+#ifdef __TIZEN_INTERNAL_BT_SCO__
bt_sco_close(u, false);
+#endif
if (u->loopback_modules) {
pa_hashmap_remove_all(u->loopback_modules);
pa_strbuf_printf(buf, " Product ID : %04x\n", device->product_id);
pa_strbuf_printf(buf, " Specified Stream role : %s\n", device->specified_stream_role);
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
if (device_type_is_equal(device->type, DEVICE_TYPE_BT_SCO))
pa_strbuf_printf(buf, " SCO opened : %s\n", pa_yes_no(device->sco_opened));
+#endif
playback_str = get_playback_list_str(device->playback_devices);
capture_str = get_capture_list_str(device->capture_devices);
device->state = DM_DEVICE_STATE_DEACTIVATED;
device->creation_time = pa_rtclock_now();
device->use_internal_codec = data->use_internal_codec;
+#ifdef __TIZEN_INTERNAL_BT_SCO__
device->sco_opened = false;
+#endif
device->is_running = false;
device->specified_stream_role = pa_xstrdup("none");
return stream_id_set;
}
+#ifdef __TIZEN_INTERNAL_BT_SCO__
static int method_call_bt_sco_enable_pcm(pa_dbus_connection *conn, bool enable) {
DBusMessage *msg, *reply;
DBusError err;
pa_log_info("BT SCO (%u) Get Status, %d", device->id, *status);
return 0;
}
+#endif /* __TIZEN_INTERNAL_BT_SCO__ */
* false, if this device uses external card(bt-a2dp, usb */
bool use_internal_codec;
/* If this is sco device, this can be used to */
+#ifdef __TIZEN_INTERNAL_BT_SCO__
bool sco_opened;
+#endif
/* Devices are contained in this list */
pa_idxset *list;
bool pa_tz_device_is_all_suspended(pa_tz_device *device);
pa_intset* pa_tz_device_get_stream_list(pa_tz_device *device);
+#ifdef __TIZEN_INTERNAL_BT_SCO__
/* Only for BT SCO device */
int pa_tz_device_sco_enable_pcm(pa_tz_device *device, bool enable);
int pa_tz_device_sco_open(pa_tz_device *device);
int pa_tz_device_sco_close(pa_tz_device *device);
int pa_tz_device_sco_get_property(pa_tz_device *device, bool *is_wide_band, bool *nrec);
int pa_tz_device_sco_get_status(pa_tz_device *device, dm_device_bt_sco_status_t *status);
+#endif
/* Only for USB device */
int pa_tz_device_get_vendor_id(pa_tz_device *device);