#define STREAM_MANAGER_METHOD_NAME_GET_CURRENT_MEDIA_ROUTING_PATH "GetCurrentMediaRoutingPath"
#define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS "UpdateFocusStatus"
#define STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION "UpdateRestriction"
+#define STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS_BY_FOCUS_ID "UpdateFocusStatusByFocusId" /* Similar to UpdateFocusStatus but using focus id, it is only for backward compatibility */
/* signal */
#define STREAM_MANAGER_SIGNAL_NAME_VOLUME_CHANGED "VolumeChanged"
#define STREAM_MANAGER_SIGNAL_NAME_COMMAND "Command"
static void handle_get_current_volume_type(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_get_current_media_routing_path(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_update_focus_status(DBusConnection *conn, DBusMessage *msg, void *userdata);
+static void handle_update_focus_status_by_focus_id(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, void *userdata);
static void send_volume_changed_signal(DBusConnection *conn, const char *direction, const char *volume_type, const uint32_t volume_level);
static void send_command_signal(DBusConnection *conn, const char *name, int value);
METHOD_HANDLER_GET_CURRENT_VOLUME_TYPE,
METHOD_HANDLER_GET_CURRENT_MEDIA_ROUTING_PATH,
METHOD_HANDLER_UPDATE_FOCUS_STATUS,
+ METHOD_HANDLER_UPDATE_FOCUS_STATUS_BY_FOCUS_ID,
METHOD_HANDLER_UPDATE_RESTRICTION,
METHOD_HANDLER_MAX
};
static pa_dbus_arg_info update_focus_status_args[] = { { "parent_id", "u", "in" },
{ "focus_status", "u", "in" },
{ "ret_msg", "s", "out" } };
+static pa_dbus_arg_info update_focus_status_by_focus_id_args[] = { { "focus_id", "i", "in" },
+ { "focus_status", "u", "in" },
+ { "ret_msg", "s", "out" } };
static pa_dbus_arg_info update_restriction_args[] = { { "name", "s", "in" },
{ "value", "u", "in" },
{ "ret_msg", "s", "out" } };
-static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "s", "uu", "su"};
+static const char* signature_args_for_in[] = { "s", "", "uauau", "usi", "ssu", "ss", "ss", "ssu", "ss", "s", "s", "uu", "iu", "su"};
static pa_dbus_method_handler method_handlers[METHOD_HANDLER_MAX] = {
[METHOD_HANDLER_GET_STREAM_INFO] = {
.arguments = update_focus_status_args,
.n_arguments = sizeof(update_focus_status_args) / sizeof(pa_dbus_arg_info),
.receive_cb = handle_update_focus_status },
+ [METHOD_HANDLER_UPDATE_FOCUS_STATUS_BY_FOCUS_ID] = {
+ .method_name = STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS_BY_FOCUS_ID,
+ .arguments = update_focus_status_by_focus_id_args,
+ .n_arguments = sizeof(update_focus_status_by_focus_id_args) / sizeof(pa_dbus_arg_info),
+ .receive_cb = handle_update_focus_status_by_focus_id },
[METHOD_HANDLER_UPDATE_RESTRICTION] = {
.method_name = STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION,
.arguments = update_restriction_args,
" <arg name=\"focus_status\" direction=\"in\" type=\"u\"/>" \
" <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>" \
" </method>" \
+ " <method name=\"STREAM_MANAGER_METHOD_NAME_UPDATE_FOCUS_STATUS_BY_FOCUS_ID\">" \
+ " <arg name=\"focus_id\" direction=\"in\" type=\"i\"/>" \
+ " <arg name=\"focus_status\" direction=\"in\" type=\"u\"/>" \
+ " <arg name=\"ret_msg\" direction=\"out\" type=\"s\"/>" \
+ " </method>" \
" <method name=\"STREAM_MANAGER_METHOD_NAME_UPDATE_RESTRICTION\">" \
" <arg name=\"name\" direction=\"in\" type=\"s\"/>" \
" <arg name=\"value\" direction=\"in\" type=\"u\"/>" \
dbus_message_unref(reply);
}
+static void handle_update_focus_status_by_focus_id(DBusConnection *conn, DBusMessage *msg, void *userdata) {
+ int32_t id = 0;
+ uint32_t idx = 0;
+ uint32_t acquired_focus_status = 0;
+ int32_t focus_id = 0;
+ const char *focus_id_str;
+ pa_sink_input *i = NULL;
+ DBusMessage *reply = NULL;
+ pa_stream_manager *m = (pa_stream_manager*)userdata;
+
+ pa_assert(conn);
+ pa_assert(msg);
+ pa_assert(m);
+
+ pa_assert_se(dbus_message_get_args(msg, NULL,
+ DBUS_TYPE_INT32, &id,
+ DBUS_TYPE_UINT32, &acquired_focus_status,
+ DBUS_TYPE_INVALID));
+ pa_log_info("handle_update_focus_status_by_focus_id(), id[%d], acquired_focus_status[0x%x]", id, acquired_focus_status);
+
+ pa_assert_se((reply = dbus_message_new_method_return(msg)));
+
+ /* Currently, we only support sink-inputs */
+ PA_IDXSET_FOREACH(i, m->core->sink_inputs, idx) {
+ if ((focus_id_str = pa_proplist_gets(GET_STREAM_PROPLIST(i, STREAM_SINK_INPUT), PA_PROP_MEDIA_FOCUS_ID))) {
+ if (pa_atoi(focus_id_str, &focus_id))
+ continue;
+ if (id == focus_id) {
+ pa_log_info("found matching sink-input(%p, %u) - focus_id(%d)", i, i->index, id);
+ pa_proplist_sets(GET_STREAM_PROPLIST(i, STREAM_SINK_INPUT), PA_PROP_MEDIA_FOCUS_STATUS,
+ acquired_focus_status ? STREAM_FOCUS_STATE_ACQUIRED : STREAM_FOCUS_STATE_RELEASED);
+ process_stream(m, i, STREAM_SINK_INPUT, PROCESS_COMMAND_CHANGE_ROUTE_BY_STREAM_FOCUS_CHANGED, false);
+
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_OK], DBUS_TYPE_INVALID));
+ goto success;
+ }
+ }
+ }
+ pa_log_error("could not find matching stream for this focus_id[%i]", id);
+ pa_assert_se(dbus_message_append_args(reply, DBUS_TYPE_STRING, &stream_manager_dbus_ret_str[RET_MSG_INDEX_ERROR], DBUS_TYPE_INVALID));
+success:
+ pa_assert_se(dbus_connection_send(conn, reply, NULL));
+ dbus_message_unref(reply);
+}
+
static void handle_update_restriction(DBusConnection *conn, DBusMessage *msg, void *userdata) {
const char *name;
uint32_t value = 0;