device-manager: Add Dbus interfaces related to sample format of usb device 32/182832/3
authorSangchul Lee <sc11.lee@samsung.com>
Thu, 28 Jun 2018 08:19:54 +0000 (17:19 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Mon, 9 Jul 2018 01:16:30 +0000 (10:16 +0900)
Methods are added as below
 - GetSupportedSampleFormats
    : arg#1 (in)  int32 for device_id
      arg#2 (out) string array for sample_formats
 - SetSampleFormat
    : arg#1 (in)  int32 for device_id
      arg#2 (in)  string for sample_format
 - GetSampleFormat
    : arg#1 (in)  int32 for device_id
      arg#2 (out) string for sample_format

Those APIs are only for usb output device.

[Version] 11.1.15
[Issue Type] New feature

Change-Id: I07e42098fabcf2d4ea8efe486c1da63da3741722
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
packaging/pulseaudio-modules-tizen.spec
src/device-manager.c

index 1fcd27b..a431c55 100644 (file)
@@ -1,6 +1,6 @@
 Name:             pulseaudio-modules-tizen
 Summary:          Pulseaudio modules for Tizen
-Version:          11.1.14
+Version:          11.1.15
 Release:          0
 Group:            Multimedia/Audio
 License:          LGPL-2.1+
index 4c4da25..1f2c416 100644 (file)
     "   <arg name=\"device_type\" direction=\"in\" type=\"s\"/>\n"                          \
     "   <arg name=\"role\" direction=\"in\" type=\"s\"/>\n"                                 \
     "  </method>\n"                                                                         \
+    "  <method name=\"GetSupportedSampleFormats\">\n"                                       \
+    "   <arg name=\"device_id\" direction=\"in\" type=\"i\"/>\n"                            \
+    "   <arg name=\"sample_formats\" direction=\"out\" type=\"a(s)\"/>\n"                   \
+    "  </method>\n"                                                                         \
+    "  <method name=\"SetSampleFormat\">\n"                                                 \
+    "   <arg name=\"device_id\" direction=\"in\" type=\"i\"/>\n"                            \
+    "   <arg name=\"sample_format\" direction=\"in\" type=\"s\"/>\n"                        \
+    "  </method>\n"                                                                         \
+    "  <method name=\"GetSampleFormat\">\n"                                                 \
+    "   <arg name=\"device_id\" direction=\"in\" type=\"i\"/>\n"                            \
+    "   <arg name=\"sample_format\" direction=\"out\" type=\"s\"/>\n"                       \
+    "  </method>\n"                                                                         \
     "  <method name=\"GetSupportedSampleRates\">\n"                                         \
     "   <arg name=\"device_id\" direction=\"in\" type=\"i\"/>\n"                            \
     "   <arg name=\"sample_rates\" direction=\"out\" type=\"a(u)\"/>\n"                     \
@@ -426,6 +438,9 @@ static void handle_get_connected_device_list(DBusConnection *conn, DBusMessage *
 static void handle_get_device_by_id(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_is_stream_on_device(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_bt_a2dp_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_supported_sample_rates(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_set_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
 static void handle_get_sample_rate(DBusConnection *conn, DBusMessage *msg, void *userdata);
@@ -449,6 +464,9 @@ enum method_handler_index {
     METHOD_HANDLER_UNLOAD_SINK,
     METHOD_HANDLER_UNLOAD_SINK_WITH_DEVICE_STRING,
     METHOD_HANDLER_GET_DEVICE_STRING,
+    METHOD_HANDLER_GET_SUPPORTED_SAMPLE_FORMATS,
+    METHOD_HANDLER_SET_SAMPLE_FORMAT,
+    METHOD_HANDLER_GET_SAMPLE_FORMAT,
     METHOD_HANDLER_GET_SUPPORTED_SAMPLE_RATES,
     METHOD_HANDLER_SET_SAMPLE_RATE,
     METHOD_HANDLER_GET_SAMPLE_RATE,
@@ -484,6 +502,15 @@ static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
     [METHOD_HANDLER_GET_DEVICE_STRING] = {
         .method_name = "GetDeviceString",
         .receive_cb = handle_get_device_string },
+    [METHOD_HANDLER_GET_SUPPORTED_SAMPLE_FORMATS] = {
+        .method_name = "GetSupportedSampleFormats",
+        .receive_cb = handle_get_supported_sample_formats },
+    [METHOD_HANDLER_SET_SAMPLE_FORMAT] = {
+        .method_name = "SetSampleFormat",
+        .receive_cb = handle_set_sample_format },
+    [METHOD_HANDLER_GET_SAMPLE_FORMAT] = {
+        .method_name = "GetSampleFormat",
+        .receive_cb = handle_get_sample_format },
     [METHOD_HANDLER_GET_SUPPORTED_SAMPLE_RATES] = {
         .method_name = "GetSupportedSampleRates",
         .receive_cb = handle_get_supported_sample_rates },
@@ -3294,12 +3321,188 @@ static bool is_usb_output_device(pa_tz_device *device) {
     return true;
 }
 
+
+static bool is_supported_sample_format(pa_sample_format_t *supported_sample_formats, pa_sample_format_t sample_format) {
+    int i;
+
+    pa_assert(supported_sample_formats);
+    pa_assert(sample_format != PA_SAMPLE_INVALID);
+
+    for (i = 0; supported_sample_formats[i] != PA_SAMPLE_MAX; i++) {
+        if (supported_sample_formats[i] == sample_format) {
+            pa_log_info("%s is supported", pa_sample_format_to_string(sample_format));
+            return true;
+        }
+    }
+    pa_log_error("%s is not supported", pa_sample_format_to_string(sample_format));
+    return false;
+}
+
+static void handle_get_supported_sample_formats(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_device_manager *dm;
+    DBusMessage *reply = NULL;
+    DBusMessageIter msg_iter, array_iter, item_iter;
+    dbus_int32_t device_id;
+    pa_tz_device *device;
+    pa_sink *sink;
+    const char *format;
+    int i;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(userdata);
+
+    dm = (pa_device_manager *)userdata;
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_INT32, &device_id,
+                                       DBUS_TYPE_INVALID));
+
+    pa_log_info("Get supported sample formats of the device(id:%d)", device_id);
+
+    if (!(device = _device_list_get_device_by_id(dm, device_id))) {
+        pa_log_error("could not find any device with id:%d", device_id);
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument");
+        return;
+    }
+    if (!is_usb_output_device(device)) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal");
+        return;
+    }
+    if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) {
+        pa_log_error("could not get sink for normal role");
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument");
+        return;
+    }
+
+    dbus_message_iter_init_append(reply, &msg_iter);
+    pa_assert_se(dbus_message_iter_open_container(&msg_iter, DBUS_TYPE_ARRAY, "(s)", &array_iter));
+    for (i = 0; sink->supported_sample_formats[i] != PA_SAMPLE_MAX; i++) {
+        format = pa_sample_format_to_string(sink->supported_sample_formats[i]);
+        pa_log_info("%s is supported", format);
+        pa_assert_se(dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &item_iter));
+        dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING, &format);
+        pa_assert_se(dbus_message_iter_close_container(&array_iter, &item_iter));
+    }
+    pa_assert_se(dbus_message_iter_close_container(&msg_iter, &array_iter));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+static void handle_set_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_device_manager *dm;
+    DBusMessage *reply = NULL;
+    dbus_int32_t device_id;
+    char *sample_format;
+    pa_sample_format_t prev_selected_sample_format;
+    pa_tz_device *device;
+    pa_sink *sink;
+    pa_sink_input *si;
+    uint32_t idx;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(userdata);
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    dm = (pa_device_manager *)userdata;
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_INT32, &device_id,
+                                       DBUS_TYPE_STRING, &sample_format,
+                                       DBUS_TYPE_INVALID));
+
+    pa_log_info("Set sample format(%s) of the device(id:%d)", sample_format, device_id);
+
+    if (!(device = _device_list_get_device_by_id(dm, device_id))) {
+        pa_log_error("could not find any device with id:%d", device_id);
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument");
+        return;
+    }
+    if (!is_usb_output_device(device)) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal");
+        return;
+    }
+    if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) {
+        pa_log_error("could not get sink for normal role");
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument");
+        return;
+    }
+
+    /* use a supported sample format selected by user */
+    if (!is_supported_sample_format(sink->supported_sample_formats, pa_parse_sample_format(sample_format))) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument");
+        return;
+    }
+    prev_selected_sample_format = sink->selected_sample_format;
+    sink->selected_sample_format = pa_parse_sample_format(sample_format);
+
+    PA_IDXSET_FOREACH(si, sink->inputs, idx) {
+        if (pa_sink_reconfigure(sink, &si->sample_spec, pa_sink_input_is_passthrough(si)) == -1) {
+            pa_log_error("failed to reconfigure");
+            pa_dbus_send_error(conn, msg, DBUS_ERROR_FAILED, "%s", "org.tizen.multimedia.audio.Internal");
+            sink->selected_sample_format = prev_selected_sample_format;
+            return;
+        }
+        break;
+    }
+
+    pa_log_info("Set sample format(%s) of the device(id:%d) successfully", sample_format, device_id);
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
+static void handle_get_sample_format(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+    pa_device_manager *dm;
+    DBusMessage *reply = NULL;
+    dbus_int32_t device_id;
+    pa_tz_device *device;
+    pa_sink *sink;
+    const char *format;
+
+    pa_assert(conn);
+    pa_assert(msg);
+    pa_assert(userdata);
+
+    dm = (pa_device_manager *)userdata;
+
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+    pa_assert_se(dbus_message_get_args(msg, NULL,
+                                       DBUS_TYPE_INT32, &device_id,
+                                       DBUS_TYPE_INVALID));
+
+    pa_log_info("Get sample format of the device(id:%d)", device_id);
+
+    if (!(device = _device_list_get_device_by_id(dm, device_id))) {
+        pa_log_error("could not find any device with id:%d", device_id);
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument");
+        return;
+    }
+    if (!is_usb_output_device(device)) {
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_NOT_SUPPORTED, "%s", "org.tizen.multimedia.audio.PolicyInternal");
+        return;
+    }
+    if (!(sink = pa_tz_device_get_sink(device, DEVICE_ROLE_NORMAL))) {
+        pa_log_error("could not get sink for normal role");
+        pa_dbus_send_error(conn, msg, DBUS_ERROR_INVALID_ARGS, "%s", "org.tizen.multimedia.audio.InvalidArgument");
+        return;
+    }
+
+    format = pa_sample_format_to_string(sink->selected_sample_format);
+    pa_log_info("Get sample format(%s) of the device(id:%d) successfully", format, device_id);
+    pa_assert_se((reply = dbus_message_new_method_return(msg)));
+    pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &format, DBUS_TYPE_INVALID));
+    pa_assert_se(dbus_connection_send(conn, reply, NULL));
+    dbus_message_unref(reply);
+}
+
 static bool is_supported_sample_rate(uint32_t *supported_sample_rates, uint32_t sample_rate) {
     int i;
 
     pa_assert(supported_sample_rates);
 
-    /* use a supported sample rate selected by user */
     for (i = 0; supported_sample_rates[i]; i++) {
         if (supported_sample_rates[i] == sample_rate) {
             pa_log_info("%u is supported", sample_rate);